From 120c9fac8d3f3754ef056fe508f439a3973fb5f5 Mon Sep 17 00:00:00 2001 From: Roscoe Rubin-Rottenberg <118622417+knotbin@users.noreply.github.com> Date: Tue, 3 Jun 2025 17:35:57 -0400 Subject: [PATCH] =?UTF-8?q?=F0=9F=A6=95=20(#16)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: daviirodrig <30713947+daviirodrig@users.noreply.github.com> --- .github/workflows/build-appview.yaml | 2 +- .github/workflows/build-cdn.yaml | 2 +- .github/workflows/build-ingester.yaml | 2 +- deno.json | 6 + deno.lock | 933 ++ lexicons/so/sprk/actor/defs.json | 9 +- lexicons/so/sprk/feed/audio.json | 2 +- lexicons/so/sprk/feed/music.json | 2 +- services/appview/.env.example | 17 - services/appview/Dockerfile | 23 +- services/appview/Dockerfile.dev | 12 +- services/appview/README.md | 40 +- .../api/com/atproto/admin/getAccountInfos.ts | 47 + .../api/com/atproto/admin/getSubjectStatus.ts | 94 + .../com/atproto/admin/updateSubjectStatus.ts | 119 + .../api/com/atproto/identity/resolveHandle.ts | 25 + .../api/com/atproto/repo/getRecord.ts | 128 +- services/appview/{src => }/api/index.ts | 16 +- .../api/so/sprk/actor/getPreferences.ts | 33 + .../{src => }/api/so/sprk/actor/getProfile.ts | 136 +- .../api/so/sprk/actor/putPreferences.ts | 61 + .../api/so/sprk/actor/searchActors.ts | 119 +- .../appview/api/so/sprk/feed/getAuthorFeed.ts | 188 + .../appview/api/so/sprk/feed/getPostThread.ts | 187 + services/appview/api/so/sprk/feed/getPosts.ts | 56 + .../appview/api/so/sprk/graph/getFollowers.ts | 126 + .../appview/api/so/sprk/graph/getFollows.ts | 169 + services/appview/compose.dev.yaml | 24 +- services/appview/deno.json | 33 + services/appview/{src => }/lexicon/index.ts | 1124 +- services/appview/lexicon/lexicons.ts | 10162 ++++++++++++++++ .../lexicon/types/com/atproto/admin/defs.ts | 102 + .../types/com/atproto/admin/deleteAccount.ts | 42 + .../atproto/admin/disableAccountInvites.ts | 44 + .../com/atproto/admin/disableInviteCodes.ts | 43 + .../com/atproto/admin/enableAccountInvites.ts | 44 + .../types/com/atproto/admin/getAccountInfo.ts | 46 + .../com/atproto/admin/getAccountInfos.ts | 50 + .../types/com/atproto/admin/getInviteCodes.ts | 53 + .../com/atproto/admin/getSubjectStatus.ts | 59 + .../types/com/atproto/admin/searchAccounts.ts | 53 + .../types/com/atproto/admin/sendEmail.ts | 57 + .../com/atproto/admin/updateAccountEmail.ts | 44 + .../com/atproto/admin/updateAccountHandle.ts | 43 + .../atproto/admin/updateAccountPassword.ts | 43 + .../com/atproto/admin/updateSubjectStatus.ts | 65 + .../identity/getRecommendedDidCredentials.ts | 51 + .../identity/requestPlcOperationSignature.ts | 36 + .../com/atproto/identity/resolveHandle.ts | 50 + .../com/atproto/identity/signPlcOperation.ts | 58 + .../atproto/identity/submitPlcOperation.ts | 42 + .../com/atproto/identity/updateHandle.ts | 43 + .../lexicon/types/com/atproto/label/defs.ts | 116 +- .../types/com/atproto/label/queryLabels.ts | 56 + .../com/atproto/label/subscribeLabels.ts | 64 + .../types/com/atproto/lexicon/schema.ts | 28 + .../com/atproto/moderation/createReport.ts | 69 + .../types/com/atproto/moderation/defs.ts | 36 + .../types/com/atproto/repo/applyWrites.ts | 166 + .../types/com/atproto/repo/createRecord.ts | 68 + .../lexicon/types/com/atproto/repo/defs.ts | 27 + .../types/com/atproto/repo/deleteRecord.ts | 63 + .../types/com/atproto/repo/describeRepo.ts | 57 + .../types/com/atproto/repo/getRecord.ts | 59 + .../types/com/atproto/repo/importRepo.ts | 41 + .../com/atproto/repo/listMissingBlobs.ts | 67 + .../types/com/atproto/repo/listRecords.ts | 79 + .../types/com/atproto/repo/putRecord.ts | 70 + .../types/com/atproto/repo/strongRef.ts | 27 + .../types/com/atproto/repo/uploadBlob.ts | 51 + .../com/atproto/server/activateAccount.ts | 36 + .../com/atproto/server/checkAccountStatus.ts | 55 + .../types/com/atproto/server/confirmEmail.ts | 44 + .../types/com/atproto/server/createAccount.ts | 80 + .../com/atproto/server/createAppPassword.ts | 72 + .../com/atproto/server/createInviteCode.ts | 53 + .../com/atproto/server/createInviteCodes.ts | 70 + .../types/com/atproto/server/createSession.ts | 68 + .../com/atproto/server/deactivateAccount.ts | 43 + .../lexicon/types/com/atproto/server/defs.ts | 48 + .../types/com/atproto/server/deleteAccount.ts | 45 + .../types/com/atproto/server/deleteSession.ts | 36 + .../com/atproto/server/describeServer.ts | 86 + .../atproto/server/getAccountInviteCodes.ts | 53 + .../com/atproto/server/getServiceAuth.ts | 55 + .../types/com/atproto/server/getSession.ts | 55 + .../com/atproto/server/listAppPasswords.ts | 65 + .../com/atproto/server/refreshSession.ts | 55 + .../atproto/server/requestAccountDelete.ts | 36 + .../server/requestEmailConfirmation.ts | 36 + .../com/atproto/server/requestEmailUpdate.ts | 47 + .../atproto/server/requestPasswordReset.ts | 42 + .../com/atproto/server/reserveSigningKey.ts | 54 + .../types/com/atproto/server/resetPassword.ts | 44 + .../com/atproto/server/revokeAppPassword.ts | 42 + .../types/com/atproto/server/updateEmail.ts | 46 + .../lexicon/types/com/atproto/sync/getBlob.ts | 54 + .../types/com/atproto/sync/getBlocks.ts | 53 + .../types/com/atproto/sync/getCheckout.ts | 46 + .../lexicon/types/com/atproto/sync/getHead.ts | 51 + .../types/com/atproto/sync/getLatestCommit.ts | 56 + .../types/com/atproto/sync/getRecord.ts | 57 + .../lexicon/types/com/atproto/sync/getRepo.ts | 53 + .../types/com/atproto/sync/getRepoStatus.ts | 56 + .../types/com/atproto/sync/listBlobs.ts | 60 + .../types/com/atproto/sync/listRepos.ts | 72 + .../com/atproto/sync/listReposByCollection.ts | 68 + .../types/com/atproto/sync/notifyOfUpdate.ts | 43 + .../types/com/atproto/sync/requestCrawl.ts | 43 + .../types/com/atproto/sync/subscribeRepos.ts | 179 +- .../com/atproto/temp/addReservedHandle.ts | 50 + .../com/atproto/temp/checkSignupQueue.ts | 49 + .../types/com/atproto/temp/fetchLabels.ts | 51 + .../atproto/temp/requestPhoneVerification.ts | 42 + .../lexicon/types/so/sprk/actor/defs.ts | 464 + .../types/so/sprk/actor/getPreferences.ts | 47 + .../lexicon/types/so/sprk/actor/getProfile.ts | 47 + .../types/so/sprk/actor/getProfiles.ts | 50 + .../types/so/sprk/actor/getSuggestions.ts | 54 + .../lexicon/types/so/sprk/actor/profile.ts | 39 + .../types/so/sprk/actor/putPreferences.ts | 42 + .../types/so/sprk/actor/searchActors.ts | 54 + .../so/sprk/actor/searchActorsTypeahead.ts | 52 + .../lexicon/types/so/sprk/embed/defs.ts | 28 + .../lexicon/types/so/sprk/embed/images.ts | 81 + .../lexicon/types/so/sprk/embed/video.ts | 66 + .../lexicon/types/so/sprk/feed/defs.ts | 434 + .../so/sprk/feed/describeFeedGenerator.ts | 80 + .../lexicon/types/so/sprk/feed/generator.ts | 41 + .../types/so/sprk/feed/getActorFeeds.ts | 53 + .../types/so/sprk/feed/getActorLikes.ts | 54 + .../types/so/sprk/feed/getActorLooks.ts | 54 + .../types/so/sprk/feed/getAuthorFeed.ts | 63 + .../lexicon/types/so/sprk/feed/getFeed.ts | 54 + .../types/so/sprk/feed/getFeedGenerator.ts | 55 + .../types/so/sprk/feed/getFeedGenerators.ts | 50 + .../types/so/sprk/feed/getFeedSkeleton.ts | 55 + .../lexicon/types/so/sprk/feed/getLikes.ts | 75 + .../lexicon/types/so/sprk/feed/getListFeed.ts | 55 + .../lexicon/types/so/sprk/feed/getLooks.ts | 75 + .../types/so/sprk/feed/getPostThread.ts | 61 + .../lexicon/types/so/sprk/feed/getPosts.ts | 51 + .../lexicon/types/so/sprk/feed/getQuotes.ts | 58 + .../types/so/sprk/feed/getRepostedBy.ts | 58 + .../types/so/sprk/feed/getSuggestedFeeds.ts | 52 + .../lexicon/types/so/sprk/feed/getTimeline.ts | 54 + .../lexicon/types/so/sprk/feed/like.ts | 29 + .../lexicon/types/so/sprk/feed/look.ts | 29 + .../lexicon/types/so/sprk/feed/post.ts | 64 + .../lexicon/types/so/sprk/feed/postgate.ts | 48 + .../lexicon/types/so/sprk/feed/repost.ts | 29 + .../lexicon/types/so/sprk/feed/searchPosts.ts | 82 +- .../types/so/sprk/feed/sendInteractions.ts | 51 + .../lexicon/types/so/sprk/feed/threadgate.ts | 100 + .../lexicon/types/so/sprk/graph/block.ts | 29 + .../lexicon/types/so/sprk/graph/defs.ts | 194 + .../lexicon/types/so/sprk/graph/follow.ts | 28 + .../so/sprk/graph/getActorStarterPacks.ts | 53 + .../lexicon/types/so/sprk/graph/getBlocks.ts | 52 + .../types/so/sprk/graph/getFollowers.ts | 54 + .../lexicon/types/so/sprk/graph/getFollows.ts | 54 + .../types/so/sprk/graph/getKnownFollowers.ts | 54 + .../lexicon/types/so/sprk/graph/getList.ts | 55 + .../types/so/sprk/graph/getListBlocks.ts | 52 + .../types/so/sprk/graph/getListMutes.ts | 52 + .../lexicon/types/so/sprk/graph/getLists.ts | 54 + .../lexicon/types/so/sprk/graph/getMutes.ts | 52 + .../types/so/sprk/graph/getRelationships.ts | 59 + .../types/so/sprk/graph/getStarterPack.ts | 51 + .../types/so/sprk/graph/getStarterPacks.ts | 50 + .../sprk/graph/getSuggestedFollowsByActor.ts | 54 + .../lexicon/types/so/sprk/graph/list.ts | 37 + .../lexicon/types/so/sprk/graph/listblock.ts | 29 + .../lexicon/types/so/sprk/graph/listitem.ts | 31 + .../lexicon/types/so/sprk/graph/muteActor.ts | 42 + .../types/so/sprk/graph/muteActorList.ts | 42 + .../lexicon/types/so/sprk/graph/muteThread.ts | 42 + .../types/so/sprk/graph/searchStarterPacks.ts | 54 + .../types/so/sprk/graph/starterpack.ts | 50 + .../types/so/sprk/graph/unmuteActor.ts | 42 + .../types/so/sprk/graph/unmuteActorList.ts | 42 + .../types/so/sprk/graph/unmuteThread.ts | 42 + .../lexicon/types/so/sprk/labeler/defs.ts | 92 + .../types/so/sprk/labeler/getServices.ts | 55 + .../lexicon/types/so/sprk/labeler/service.ts | 31 + .../so/sprk/notification/getUnreadCount.ts | 50 + .../so/sprk/notification/listNotifications.ts | 91 + .../so/sprk/notification/putPreferences.ts | 42 + .../so/sprk/notification/registerPush.ts | 45 + .../types/so/sprk/notification/updateSeen.ts | 42 + .../lexicon/types/so/sprk/richtext/facet.ts | 67 +- .../lexicon/types/so/sprk/unspecced/defs.ts | 78 + .../types/so/sprk/unspecced/getConfig.ts | 47 + .../unspecced/getPopularFeedGenerators.ts | 53 + .../sprk/unspecced/getSuggestionsSkeleton.ts | 60 + .../so/sprk/unspecced/getTaggedSuggestions.ts | 64 + .../so/sprk/unspecced/getTrendingTopics.ts | 53 + .../so/sprk/unspecced/searchActorsSkeleton.ts | 62 + .../so/sprk/unspecced/searchPostsSkeleton.ts | 84 +- .../unspecced/searchStarterPacksSkeleton.ts | 60 + .../lexicon/types/so/sprk/video/defs.ts | 34 + .../types/so/sprk/video/getJobStatus.ts | 50 + .../types/so/sprk/video/getUploadLimits.ts | 51 + .../types/so/sprk/video/uploadVideo.ts | 52 + services/appview/{src => }/lexicon/util.ts | 59 +- services/appview/main.ts | 159 + services/appview/main_test.ts | 49 + services/appview/package.json | 65 - services/appview/pnpm-lock.yaml | 2852 ----- .../appview/services/auth/auth-verifier.ts | 584 + services/appview/services/auth/middleware.ts | 144 + .../data-plane/client/hosts.ts | 84 +- .../services/data-plane/client/index.ts | 160 + .../services/data-plane/client/util.ts | 96 + .../data-plane/server/index.ts | 630 +- .../appview/{src => }/services/indexing.ts | 180 +- .../{src => }/services/plugins/bskyFollow.ts | 89 +- .../{src => }/services/plugins/post.ts | 125 +- .../takedown-filter.ts | 268 +- .../appview/{src => }/services/takedown.ts | 270 +- services/appview/src/api/admin/takedowns.ts | 273 - .../api/com/atproto/admin/getAccountInfos.ts | 43 - .../api/com/atproto/admin/getSubjectStatus.ts | 94 - .../com/atproto/admin/updateSubjectStatus.ts | 98 - .../api/com/atproto/identity/resolveHandle.ts | 26 - .../src/api/so/sprk/actor/getPreferences.ts | 31 - .../src/api/so/sprk/actor/putPreferences.ts | 62 - .../src/api/so/sprk/feed/getAuthorFeed.ts | 178 - .../src/api/so/sprk/feed/getPostThread.ts | 161 - .../appview/src/api/so/sprk/feed/getPosts.ts | 54 - .../src/api/so/sprk/graph/getFollowers.ts | 114 - .../src/api/so/sprk/graph/getFollows.ts | 152 - services/appview/src/auth/auth-verifier.ts | 580 - services/appview/src/auth/middleware.ts | 134 - .../appview/src/data-plane/client/index.ts | 151 - .../appview/src/data-plane/client/util.ts | 95 - services/appview/src/env.ts | 22 - services/appview/src/index.ts | 208 - services/appview/src/lexicon/lexicons.ts | 10159 --------------- .../lexicon/types/com/atproto/admin/defs.ts | 102 - .../types/com/atproto/admin/deleteAccount.ts | 42 - .../atproto/admin/disableAccountInvites.ts | 44 - .../com/atproto/admin/disableInviteCodes.ts | 43 - .../com/atproto/admin/enableAccountInvites.ts | 44 - .../types/com/atproto/admin/getAccountInfo.ts | 46 - .../com/atproto/admin/getAccountInfos.ts | 50 - .../types/com/atproto/admin/getInviteCodes.ts | 53 - .../com/atproto/admin/getSubjectStatus.ts | 59 - .../types/com/atproto/admin/searchAccounts.ts | 53 - .../types/com/atproto/admin/sendEmail.ts | 57 - .../com/atproto/admin/updateAccountEmail.ts | 44 - .../com/atproto/admin/updateAccountHandle.ts | 43 - .../atproto/admin/updateAccountPassword.ts | 43 - .../com/atproto/admin/updateSubjectStatus.ts | 65 - .../identity/getRecommendedDidCredentials.ts | 51 - .../identity/requestPlcOperationSignature.ts | 36 - .../com/atproto/identity/resolveHandle.ts | 50 - .../com/atproto/identity/signPlcOperation.ts | 58 - .../atproto/identity/submitPlcOperation.ts | 42 - .../com/atproto/identity/updateHandle.ts | 43 - .../types/com/atproto/label/queryLabels.ts | 56 - .../com/atproto/label/subscribeLabels.ts | 64 - .../types/com/atproto/lexicon/schema.ts | 28 - .../com/atproto/moderation/createReport.ts | 69 - .../types/com/atproto/moderation/defs.ts | 36 - .../types/com/atproto/repo/applyWrites.ts | 166 - .../types/com/atproto/repo/createRecord.ts | 68 - .../lexicon/types/com/atproto/repo/defs.ts | 27 - .../types/com/atproto/repo/deleteRecord.ts | 63 - .../types/com/atproto/repo/describeRepo.ts | 57 - .../types/com/atproto/repo/getRecord.ts | 59 - .../types/com/atproto/repo/importRepo.ts | 41 - .../com/atproto/repo/listMissingBlobs.ts | 67 - .../types/com/atproto/repo/listRecords.ts | 79 - .../types/com/atproto/repo/putRecord.ts | 70 - .../types/com/atproto/repo/strongRef.ts | 27 - .../types/com/atproto/repo/uploadBlob.ts | 51 - .../com/atproto/server/activateAccount.ts | 36 - .../com/atproto/server/checkAccountStatus.ts | 55 - .../types/com/atproto/server/confirmEmail.ts | 44 - .../types/com/atproto/server/createAccount.ts | 80 - .../com/atproto/server/createAppPassword.ts | 72 - .../com/atproto/server/createInviteCode.ts | 53 - .../com/atproto/server/createInviteCodes.ts | 70 - .../types/com/atproto/server/createSession.ts | 68 - .../com/atproto/server/deactivateAccount.ts | 43 - .../lexicon/types/com/atproto/server/defs.ts | 48 - .../types/com/atproto/server/deleteAccount.ts | 45 - .../types/com/atproto/server/deleteSession.ts | 36 - .../com/atproto/server/describeServer.ts | 86 - .../atproto/server/getAccountInviteCodes.ts | 53 - .../com/atproto/server/getServiceAuth.ts | 55 - .../types/com/atproto/server/getSession.ts | 55 - .../com/atproto/server/listAppPasswords.ts | 65 - .../com/atproto/server/refreshSession.ts | 55 - .../atproto/server/requestAccountDelete.ts | 36 - .../server/requestEmailConfirmation.ts | 36 - .../com/atproto/server/requestEmailUpdate.ts | 47 - .../atproto/server/requestPasswordReset.ts | 42 - .../com/atproto/server/reserveSigningKey.ts | 54 - .../types/com/atproto/server/resetPassword.ts | 44 - .../com/atproto/server/revokeAppPassword.ts | 42 - .../types/com/atproto/server/updateEmail.ts | 46 - .../lexicon/types/com/atproto/sync/getBlob.ts | 54 - .../types/com/atproto/sync/getBlocks.ts | 53 - .../types/com/atproto/sync/getCheckout.ts | 46 - .../lexicon/types/com/atproto/sync/getHead.ts | 51 - .../types/com/atproto/sync/getLatestCommit.ts | 52 - .../types/com/atproto/sync/getRecord.ts | 57 - .../lexicon/types/com/atproto/sync/getRepo.ts | 49 - .../types/com/atproto/sync/getRepoStatus.ts | 56 - .../types/com/atproto/sync/listBlobs.ts | 56 - .../types/com/atproto/sync/listRepos.ts | 72 - .../com/atproto/sync/listReposByCollection.ts | 68 - .../types/com/atproto/sync/notifyOfUpdate.ts | 43 - .../types/com/atproto/sync/requestCrawl.ts | 43 - .../com/atproto/temp/addReservedHandle.ts | 50 - .../com/atproto/temp/checkSignupQueue.ts | 49 - .../types/com/atproto/temp/fetchLabels.ts | 51 - .../atproto/temp/requestPhoneVerification.ts | 42 - .../src/lexicon/types/so/sprk/actor/defs.ts | 464 - .../types/so/sprk/actor/getPreferences.ts | 47 - .../lexicon/types/so/sprk/actor/getProfile.ts | 47 - .../types/so/sprk/actor/getProfiles.ts | 50 - .../types/so/sprk/actor/getSuggestions.ts | 54 - .../lexicon/types/so/sprk/actor/profile.ts | 39 - .../types/so/sprk/actor/putPreferences.ts | 42 - .../types/so/sprk/actor/searchActors.ts | 54 - .../so/sprk/actor/searchActorsTypeahead.ts | 52 - .../src/lexicon/types/so/sprk/embed/defs.ts | 28 - .../src/lexicon/types/so/sprk/embed/images.ts | 81 - .../src/lexicon/types/so/sprk/embed/video.ts | 66 - .../src/lexicon/types/so/sprk/feed/defs.ts | 434 - .../so/sprk/feed/describeFeedGenerator.ts | 80 - .../lexicon/types/so/sprk/feed/generator.ts | 41 - .../types/so/sprk/feed/getActorFeeds.ts | 53 - .../types/so/sprk/feed/getActorLikes.ts | 54 - .../types/so/sprk/feed/getActorLooks.ts | 54 - .../types/so/sprk/feed/getAuthorFeed.ts | 63 - .../src/lexicon/types/so/sprk/feed/getFeed.ts | 54 - .../types/so/sprk/feed/getFeedGenerator.ts | 55 - .../types/so/sprk/feed/getFeedGenerators.ts | 50 - .../types/so/sprk/feed/getFeedSkeleton.ts | 55 - .../lexicon/types/so/sprk/feed/getLikes.ts | 75 - .../lexicon/types/so/sprk/feed/getListFeed.ts | 55 - .../lexicon/types/so/sprk/feed/getLooks.ts | 75 - .../types/so/sprk/feed/getPostThread.ts | 61 - .../lexicon/types/so/sprk/feed/getPosts.ts | 51 - .../lexicon/types/so/sprk/feed/getQuotes.ts | 58 - .../types/so/sprk/feed/getRepostedBy.ts | 58 - .../types/so/sprk/feed/getSuggestedFeeds.ts | 52 - .../lexicon/types/so/sprk/feed/getTimeline.ts | 54 - .../src/lexicon/types/so/sprk/feed/like.ts | 29 - .../src/lexicon/types/so/sprk/feed/look.ts | 29 - .../src/lexicon/types/so/sprk/feed/post.ts | 64 - .../lexicon/types/so/sprk/feed/postgate.ts | 48 - .../src/lexicon/types/so/sprk/feed/repost.ts | 29 - .../types/so/sprk/feed/sendInteractions.ts | 51 - .../lexicon/types/so/sprk/feed/threadgate.ts | 100 - .../src/lexicon/types/so/sprk/graph/block.ts | 29 - .../src/lexicon/types/so/sprk/graph/defs.ts | 194 - .../src/lexicon/types/so/sprk/graph/follow.ts | 28 - .../so/sprk/graph/getActorStarterPacks.ts | 53 - .../lexicon/types/so/sprk/graph/getBlocks.ts | 52 - .../types/so/sprk/graph/getFollowers.ts | 54 - .../lexicon/types/so/sprk/graph/getFollows.ts | 54 - .../types/so/sprk/graph/getKnownFollowers.ts | 54 - .../lexicon/types/so/sprk/graph/getList.ts | 55 - .../types/so/sprk/graph/getListBlocks.ts | 52 - .../types/so/sprk/graph/getListMutes.ts | 52 - .../lexicon/types/so/sprk/graph/getLists.ts | 54 - .../lexicon/types/so/sprk/graph/getMutes.ts | 52 - .../types/so/sprk/graph/getRelationships.ts | 59 - .../types/so/sprk/graph/getStarterPack.ts | 51 - .../types/so/sprk/graph/getStarterPacks.ts | 50 - .../sprk/graph/getSuggestedFollowsByActor.ts | 54 - .../src/lexicon/types/so/sprk/graph/list.ts | 37 - .../lexicon/types/so/sprk/graph/listblock.ts | 29 - .../lexicon/types/so/sprk/graph/listitem.ts | 31 - .../lexicon/types/so/sprk/graph/muteActor.ts | 42 - .../types/so/sprk/graph/muteActorList.ts | 42 - .../lexicon/types/so/sprk/graph/muteThread.ts | 42 - .../types/so/sprk/graph/searchStarterPacks.ts | 54 - .../types/so/sprk/graph/starterpack.ts | 50 - .../types/so/sprk/graph/unmuteActor.ts | 42 - .../types/so/sprk/graph/unmuteActorList.ts | 42 - .../types/so/sprk/graph/unmuteThread.ts | 42 - .../src/lexicon/types/so/sprk/labeler/defs.ts | 92 - .../types/so/sprk/labeler/getServices.ts | 55 - .../lexicon/types/so/sprk/labeler/service.ts | 31 - .../so/sprk/notification/getUnreadCount.ts | 50 - .../so/sprk/notification/listNotifications.ts | 91 - .../so/sprk/notification/putPreferences.ts | 42 - .../so/sprk/notification/registerPush.ts | 45 - .../types/so/sprk/notification/updateSeen.ts | 42 - .../lexicon/types/so/sprk/unspecced/defs.ts | 78 - .../types/so/sprk/unspecced/getConfig.ts | 47 - .../unspecced/getPopularFeedGenerators.ts | 53 - .../sprk/unspecced/getSuggestionsSkeleton.ts | 60 - .../so/sprk/unspecced/getTaggedSuggestions.ts | 64 - .../so/sprk/unspecced/getTrendingTopics.ts | 53 - .../so/sprk/unspecced/searchActorsSkeleton.ts | 62 - .../unspecced/searchStarterPacksSkeleton.ts | 60 - .../src/lexicon/types/so/sprk/video/defs.ts | 34 - .../types/so/sprk/video/getJobStatus.ts | 50 - .../types/so/sprk/video/getUploadLimits.ts | 51 - .../types/so/sprk/video/uploadVideo.ts | 52 - services/appview/src/utils/express-adapter.ts | 63 - services/appview/tsconfig.json | 21 - services/appview/utils/env.ts | 22 + services/appview/utils/express-adapter.ts | 72 + .../appview/{src => utils}/id-resolver.ts | 46 +- .../{src => }/utils/post-transformer.ts | 91 +- services/appview/{src => utils}/well-known.ts | 34 +- services/cdn/README.md | 3 +- services/cdn/src/id-resolver.ts | 46 +- services/cdn/src/imageHandler.ts | 209 +- services/cdn/src/index.ts | 106 +- services/cdn/src/videoHandler.ts | 160 +- services/dev-env/CHANGELOG.md | 614 +- services/dev-env/README.md | 15 +- services/dev-env/pnpm-lock.yaml | 4997 +++++--- services/dev-env/src/bin.ts | 44 +- services/dev-env/src/bsky.ts | 116 +- services/dev-env/src/bsync.ts | 26 +- services/dev-env/src/const.ts | 6 +- services/dev-env/src/env.ts | 8 +- services/dev-env/src/feed-gen.ts | 78 +- services/dev-env/src/index.ts | 28 +- services/dev-env/src/introspect.ts | 32 +- services/dev-env/src/mock/data.ts | 24 +- .../src/mock/img/blur-hash-avatar-b64.ts | 2 +- .../dev-env/src/mock/img/labeled-img-b64.ts | 2 +- services/dev-env/src/mock/index.ts | 380 +- services/dev-env/src/moderator-client.ts | 136 +- services/dev-env/src/network-no-appview.ts | 42 +- services/dev-env/src/network.ts | 161 +- services/dev-env/src/ozone-service-profile.ts | 404 +- services/dev-env/src/ozone.ts | 153 +- services/dev-env/src/pds.ts | 6 +- services/dev-env/src/plc.ts | 26 +- services/dev-env/src/seed/author-feed.ts | 74 +- services/dev-env/src/seed/basic.ts | 156 +- services/dev-env/src/seed/client.ts | 385 +- services/dev-env/src/seed/follows.ts | 86 +- services/dev-env/src/seed/index.ts | 18 +- services/dev-env/src/seed/likes.ts | 48 +- services/dev-env/src/seed/quotes.ts | 42 +- services/dev-env/src/seed/reposts.ts | 32 +- services/dev-env/src/seed/users-bulk.ts | 424 +- services/dev-env/src/seed/users.ts | 58 +- services/dev-env/src/types.ts | 84 +- services/dev-env/src/util.ts | 102 +- services/dev-env/tsconfig.build.json | 2 +- services/dev-infra/README.md | 43 +- services/dev-infra/docker-compose.yaml | 14 +- services/ingester/README.md | 6 +- services/ingester/package.json | 2 +- services/ingester/src/db/connection.ts | 103 +- services/ingester/src/db/models.ts | 440 +- .../ingester/src/handlers/actor-handler.ts | 86 +- .../ingester/src/handlers/audio-handler.ts | 81 +- .../ingester/src/handlers/block-handler.ts | 79 +- .../src/handlers/bsky/follow-handler.ts | 75 +- .../ingester/src/handlers/follow-handler.ts | 82 +- .../src/handlers/generator-handler.ts | 79 +- services/ingester/src/handlers/index.ts | 122 +- .../ingester/src/handlers/like-handler.ts | 67 +- .../ingester/src/handlers/look-handler.ts | 81 +- .../ingester/src/handlers/music-handler.ts | 79 +- .../ingester/src/handlers/post-handler.ts | 73 +- .../ingester/src/handlers/profile-handler.ts | 95 +- .../ingester/src/handlers/repost-handler.ts | 84 +- services/ingester/src/index.ts | 59 +- services/ingester/src/services/indexing.ts | 65 +- services/ingester/src/types/events.ts | 52 +- services/ingester/src/utils/actor-cache.ts | 75 +- services/ingester/src/utils/actor-utils.ts | 54 +- services/ingester/src/utils/env.ts | 27 +- services/ingester/src/utils/id-resolver.ts | 52 +- .../ingester/src/utils/jetstream-client.ts | 154 +- services/ingester/src/utils/logger-config.ts | 14 +- 482 files changed, 32050 insertions(+), 32407 deletions(-) create mode 100644 deno.json create mode 100644 deno.lock delete mode 100644 services/appview/.env.example create mode 100644 services/appview/api/com/atproto/admin/getAccountInfos.ts create mode 100644 services/appview/api/com/atproto/admin/getSubjectStatus.ts create mode 100644 services/appview/api/com/atproto/admin/updateSubjectStatus.ts create mode 100644 services/appview/api/com/atproto/identity/resolveHandle.ts rename services/appview/{src => }/api/com/atproto/repo/getRecord.ts (56%) rename services/appview/{src => }/api/index.ts (53%) create mode 100644 services/appview/api/so/sprk/actor/getPreferences.ts rename services/appview/{src => }/api/so/sprk/actor/getProfile.ts (62%) create mode 100644 services/appview/api/so/sprk/actor/putPreferences.ts rename services/appview/{src => }/api/so/sprk/actor/searchActors.ts (53%) create mode 100644 services/appview/api/so/sprk/feed/getAuthorFeed.ts create mode 100644 services/appview/api/so/sprk/feed/getPostThread.ts create mode 100644 services/appview/api/so/sprk/feed/getPosts.ts create mode 100644 services/appview/api/so/sprk/graph/getFollowers.ts create mode 100644 services/appview/api/so/sprk/graph/getFollows.ts create mode 100644 services/appview/deno.json rename services/appview/{src => }/lexicon/index.ts (50%) create mode 100644 services/appview/lexicon/lexicons.ts create mode 100644 services/appview/lexicon/types/com/atproto/admin/defs.ts create mode 100644 services/appview/lexicon/types/com/atproto/admin/deleteAccount.ts create mode 100644 services/appview/lexicon/types/com/atproto/admin/disableAccountInvites.ts create mode 100644 services/appview/lexicon/types/com/atproto/admin/disableInviteCodes.ts create mode 100644 services/appview/lexicon/types/com/atproto/admin/enableAccountInvites.ts create mode 100644 services/appview/lexicon/types/com/atproto/admin/getAccountInfo.ts create mode 100644 services/appview/lexicon/types/com/atproto/admin/getAccountInfos.ts create mode 100644 services/appview/lexicon/types/com/atproto/admin/getInviteCodes.ts create mode 100644 services/appview/lexicon/types/com/atproto/admin/getSubjectStatus.ts create mode 100644 services/appview/lexicon/types/com/atproto/admin/searchAccounts.ts create mode 100644 services/appview/lexicon/types/com/atproto/admin/sendEmail.ts create mode 100644 services/appview/lexicon/types/com/atproto/admin/updateAccountEmail.ts create mode 100644 services/appview/lexicon/types/com/atproto/admin/updateAccountHandle.ts create mode 100644 services/appview/lexicon/types/com/atproto/admin/updateAccountPassword.ts create mode 100644 services/appview/lexicon/types/com/atproto/admin/updateSubjectStatus.ts create mode 100644 services/appview/lexicon/types/com/atproto/identity/getRecommendedDidCredentials.ts create mode 100644 services/appview/lexicon/types/com/atproto/identity/requestPlcOperationSignature.ts create mode 100644 services/appview/lexicon/types/com/atproto/identity/resolveHandle.ts create mode 100644 services/appview/lexicon/types/com/atproto/identity/signPlcOperation.ts create mode 100644 services/appview/lexicon/types/com/atproto/identity/submitPlcOperation.ts create mode 100644 services/appview/lexicon/types/com/atproto/identity/updateHandle.ts rename services/appview/{src => }/lexicon/types/com/atproto/label/defs.ts (60%) create mode 100644 services/appview/lexicon/types/com/atproto/label/queryLabels.ts create mode 100644 services/appview/lexicon/types/com/atproto/label/subscribeLabels.ts create mode 100644 services/appview/lexicon/types/com/atproto/lexicon/schema.ts create mode 100644 services/appview/lexicon/types/com/atproto/moderation/createReport.ts create mode 100644 services/appview/lexicon/types/com/atproto/moderation/defs.ts create mode 100644 services/appview/lexicon/types/com/atproto/repo/applyWrites.ts create mode 100644 services/appview/lexicon/types/com/atproto/repo/createRecord.ts create mode 100644 services/appview/lexicon/types/com/atproto/repo/defs.ts create mode 100644 services/appview/lexicon/types/com/atproto/repo/deleteRecord.ts create mode 100644 services/appview/lexicon/types/com/atproto/repo/describeRepo.ts create mode 100644 services/appview/lexicon/types/com/atproto/repo/getRecord.ts create mode 100644 services/appview/lexicon/types/com/atproto/repo/importRepo.ts create mode 100644 services/appview/lexicon/types/com/atproto/repo/listMissingBlobs.ts create mode 100644 services/appview/lexicon/types/com/atproto/repo/listRecords.ts create mode 100644 services/appview/lexicon/types/com/atproto/repo/putRecord.ts create mode 100644 services/appview/lexicon/types/com/atproto/repo/strongRef.ts create mode 100644 services/appview/lexicon/types/com/atproto/repo/uploadBlob.ts create mode 100644 services/appview/lexicon/types/com/atproto/server/activateAccount.ts create mode 100644 services/appview/lexicon/types/com/atproto/server/checkAccountStatus.ts create mode 100644 services/appview/lexicon/types/com/atproto/server/confirmEmail.ts create mode 100644 services/appview/lexicon/types/com/atproto/server/createAccount.ts create mode 100644 services/appview/lexicon/types/com/atproto/server/createAppPassword.ts create mode 100644 services/appview/lexicon/types/com/atproto/server/createInviteCode.ts create mode 100644 services/appview/lexicon/types/com/atproto/server/createInviteCodes.ts create mode 100644 services/appview/lexicon/types/com/atproto/server/createSession.ts create mode 100644 services/appview/lexicon/types/com/atproto/server/deactivateAccount.ts create mode 100644 services/appview/lexicon/types/com/atproto/server/defs.ts create mode 100644 services/appview/lexicon/types/com/atproto/server/deleteAccount.ts create mode 100644 services/appview/lexicon/types/com/atproto/server/deleteSession.ts create mode 100644 services/appview/lexicon/types/com/atproto/server/describeServer.ts create mode 100644 services/appview/lexicon/types/com/atproto/server/getAccountInviteCodes.ts create mode 100644 services/appview/lexicon/types/com/atproto/server/getServiceAuth.ts create mode 100644 services/appview/lexicon/types/com/atproto/server/getSession.ts create mode 100644 services/appview/lexicon/types/com/atproto/server/listAppPasswords.ts create mode 100644 services/appview/lexicon/types/com/atproto/server/refreshSession.ts create mode 100644 services/appview/lexicon/types/com/atproto/server/requestAccountDelete.ts create mode 100644 services/appview/lexicon/types/com/atproto/server/requestEmailConfirmation.ts create mode 100644 services/appview/lexicon/types/com/atproto/server/requestEmailUpdate.ts create mode 100644 services/appview/lexicon/types/com/atproto/server/requestPasswordReset.ts create mode 100644 services/appview/lexicon/types/com/atproto/server/reserveSigningKey.ts create mode 100644 services/appview/lexicon/types/com/atproto/server/resetPassword.ts create mode 100644 services/appview/lexicon/types/com/atproto/server/revokeAppPassword.ts create mode 100644 services/appview/lexicon/types/com/atproto/server/updateEmail.ts create mode 100644 services/appview/lexicon/types/com/atproto/sync/getBlob.ts create mode 100644 services/appview/lexicon/types/com/atproto/sync/getBlocks.ts create mode 100644 services/appview/lexicon/types/com/atproto/sync/getCheckout.ts create mode 100644 services/appview/lexicon/types/com/atproto/sync/getHead.ts create mode 100644 services/appview/lexicon/types/com/atproto/sync/getLatestCommit.ts create mode 100644 services/appview/lexicon/types/com/atproto/sync/getRecord.ts create mode 100644 services/appview/lexicon/types/com/atproto/sync/getRepo.ts create mode 100644 services/appview/lexicon/types/com/atproto/sync/getRepoStatus.ts create mode 100644 services/appview/lexicon/types/com/atproto/sync/listBlobs.ts create mode 100644 services/appview/lexicon/types/com/atproto/sync/listRepos.ts create mode 100644 services/appview/lexicon/types/com/atproto/sync/listReposByCollection.ts create mode 100644 services/appview/lexicon/types/com/atproto/sync/notifyOfUpdate.ts create mode 100644 services/appview/lexicon/types/com/atproto/sync/requestCrawl.ts rename services/appview/{src => }/lexicon/types/com/atproto/sync/subscribeRepos.ts (55%) create mode 100644 services/appview/lexicon/types/com/atproto/temp/addReservedHandle.ts create mode 100644 services/appview/lexicon/types/com/atproto/temp/checkSignupQueue.ts create mode 100644 services/appview/lexicon/types/com/atproto/temp/fetchLabels.ts create mode 100644 services/appview/lexicon/types/com/atproto/temp/requestPhoneVerification.ts create mode 100644 services/appview/lexicon/types/so/sprk/actor/defs.ts create mode 100644 services/appview/lexicon/types/so/sprk/actor/getPreferences.ts create mode 100644 services/appview/lexicon/types/so/sprk/actor/getProfile.ts create mode 100644 services/appview/lexicon/types/so/sprk/actor/getProfiles.ts create mode 100644 services/appview/lexicon/types/so/sprk/actor/getSuggestions.ts create mode 100644 services/appview/lexicon/types/so/sprk/actor/profile.ts create mode 100644 services/appview/lexicon/types/so/sprk/actor/putPreferences.ts create mode 100644 services/appview/lexicon/types/so/sprk/actor/searchActors.ts create mode 100644 services/appview/lexicon/types/so/sprk/actor/searchActorsTypeahead.ts create mode 100644 services/appview/lexicon/types/so/sprk/embed/defs.ts create mode 100644 services/appview/lexicon/types/so/sprk/embed/images.ts create mode 100644 services/appview/lexicon/types/so/sprk/embed/video.ts create mode 100644 services/appview/lexicon/types/so/sprk/feed/defs.ts create mode 100644 services/appview/lexicon/types/so/sprk/feed/describeFeedGenerator.ts create mode 100644 services/appview/lexicon/types/so/sprk/feed/generator.ts create mode 100644 services/appview/lexicon/types/so/sprk/feed/getActorFeeds.ts create mode 100644 services/appview/lexicon/types/so/sprk/feed/getActorLikes.ts create mode 100644 services/appview/lexicon/types/so/sprk/feed/getActorLooks.ts create mode 100644 services/appview/lexicon/types/so/sprk/feed/getAuthorFeed.ts create mode 100644 services/appview/lexicon/types/so/sprk/feed/getFeed.ts create mode 100644 services/appview/lexicon/types/so/sprk/feed/getFeedGenerator.ts create mode 100644 services/appview/lexicon/types/so/sprk/feed/getFeedGenerators.ts create mode 100644 services/appview/lexicon/types/so/sprk/feed/getFeedSkeleton.ts create mode 100644 services/appview/lexicon/types/so/sprk/feed/getLikes.ts create mode 100644 services/appview/lexicon/types/so/sprk/feed/getListFeed.ts create mode 100644 services/appview/lexicon/types/so/sprk/feed/getLooks.ts create mode 100644 services/appview/lexicon/types/so/sprk/feed/getPostThread.ts create mode 100644 services/appview/lexicon/types/so/sprk/feed/getPosts.ts create mode 100644 services/appview/lexicon/types/so/sprk/feed/getQuotes.ts create mode 100644 services/appview/lexicon/types/so/sprk/feed/getRepostedBy.ts create mode 100644 services/appview/lexicon/types/so/sprk/feed/getSuggestedFeeds.ts create mode 100644 services/appview/lexicon/types/so/sprk/feed/getTimeline.ts create mode 100644 services/appview/lexicon/types/so/sprk/feed/like.ts create mode 100644 services/appview/lexicon/types/so/sprk/feed/look.ts create mode 100644 services/appview/lexicon/types/so/sprk/feed/post.ts create mode 100644 services/appview/lexicon/types/so/sprk/feed/postgate.ts create mode 100644 services/appview/lexicon/types/so/sprk/feed/repost.ts rename services/appview/{src => }/lexicon/types/so/sprk/feed/searchPosts.ts (62%) create mode 100644 services/appview/lexicon/types/so/sprk/feed/sendInteractions.ts create mode 100644 services/appview/lexicon/types/so/sprk/feed/threadgate.ts create mode 100644 services/appview/lexicon/types/so/sprk/graph/block.ts create mode 100644 services/appview/lexicon/types/so/sprk/graph/defs.ts create mode 100644 services/appview/lexicon/types/so/sprk/graph/follow.ts create mode 100644 services/appview/lexicon/types/so/sprk/graph/getActorStarterPacks.ts create mode 100644 services/appview/lexicon/types/so/sprk/graph/getBlocks.ts create mode 100644 services/appview/lexicon/types/so/sprk/graph/getFollowers.ts create mode 100644 services/appview/lexicon/types/so/sprk/graph/getFollows.ts create mode 100644 services/appview/lexicon/types/so/sprk/graph/getKnownFollowers.ts create mode 100644 services/appview/lexicon/types/so/sprk/graph/getList.ts create mode 100644 services/appview/lexicon/types/so/sprk/graph/getListBlocks.ts create mode 100644 services/appview/lexicon/types/so/sprk/graph/getListMutes.ts create mode 100644 services/appview/lexicon/types/so/sprk/graph/getLists.ts create mode 100644 services/appview/lexicon/types/so/sprk/graph/getMutes.ts create mode 100644 services/appview/lexicon/types/so/sprk/graph/getRelationships.ts create mode 100644 services/appview/lexicon/types/so/sprk/graph/getStarterPack.ts create mode 100644 services/appview/lexicon/types/so/sprk/graph/getStarterPacks.ts create mode 100644 services/appview/lexicon/types/so/sprk/graph/getSuggestedFollowsByActor.ts create mode 100644 services/appview/lexicon/types/so/sprk/graph/list.ts create mode 100644 services/appview/lexicon/types/so/sprk/graph/listblock.ts create mode 100644 services/appview/lexicon/types/so/sprk/graph/listitem.ts create mode 100644 services/appview/lexicon/types/so/sprk/graph/muteActor.ts create mode 100644 services/appview/lexicon/types/so/sprk/graph/muteActorList.ts create mode 100644 services/appview/lexicon/types/so/sprk/graph/muteThread.ts create mode 100644 services/appview/lexicon/types/so/sprk/graph/searchStarterPacks.ts create mode 100644 services/appview/lexicon/types/so/sprk/graph/starterpack.ts create mode 100644 services/appview/lexicon/types/so/sprk/graph/unmuteActor.ts create mode 100644 services/appview/lexicon/types/so/sprk/graph/unmuteActorList.ts create mode 100644 services/appview/lexicon/types/so/sprk/graph/unmuteThread.ts create mode 100644 services/appview/lexicon/types/so/sprk/labeler/defs.ts create mode 100644 services/appview/lexicon/types/so/sprk/labeler/getServices.ts create mode 100644 services/appview/lexicon/types/so/sprk/labeler/service.ts create mode 100644 services/appview/lexicon/types/so/sprk/notification/getUnreadCount.ts create mode 100644 services/appview/lexicon/types/so/sprk/notification/listNotifications.ts create mode 100644 services/appview/lexicon/types/so/sprk/notification/putPreferences.ts create mode 100644 services/appview/lexicon/types/so/sprk/notification/registerPush.ts create mode 100644 services/appview/lexicon/types/so/sprk/notification/updateSeen.ts rename services/appview/{src => }/lexicon/types/so/sprk/richtext/facet.ts (53%) create mode 100644 services/appview/lexicon/types/so/sprk/unspecced/defs.ts create mode 100644 services/appview/lexicon/types/so/sprk/unspecced/getConfig.ts create mode 100644 services/appview/lexicon/types/so/sprk/unspecced/getPopularFeedGenerators.ts create mode 100644 services/appview/lexicon/types/so/sprk/unspecced/getSuggestionsSkeleton.ts create mode 100644 services/appview/lexicon/types/so/sprk/unspecced/getTaggedSuggestions.ts create mode 100644 services/appview/lexicon/types/so/sprk/unspecced/getTrendingTopics.ts create mode 100644 services/appview/lexicon/types/so/sprk/unspecced/searchActorsSkeleton.ts rename services/appview/{src => }/lexicon/types/so/sprk/unspecced/searchPostsSkeleton.ts (63%) create mode 100644 services/appview/lexicon/types/so/sprk/unspecced/searchStarterPacksSkeleton.ts create mode 100644 services/appview/lexicon/types/so/sprk/video/defs.ts create mode 100644 services/appview/lexicon/types/so/sprk/video/getJobStatus.ts create mode 100644 services/appview/lexicon/types/so/sprk/video/getUploadLimits.ts create mode 100644 services/appview/lexicon/types/so/sprk/video/uploadVideo.ts rename services/appview/{src => }/lexicon/util.ts (58%) create mode 100644 services/appview/main.ts create mode 100644 services/appview/main_test.ts delete mode 100644 services/appview/package.json delete mode 100644 services/appview/pnpm-lock.yaml create mode 100644 services/appview/services/auth/auth-verifier.ts create mode 100644 services/appview/services/auth/middleware.ts rename services/appview/{src => services}/data-plane/client/hosts.ts (52%) create mode 100644 services/appview/services/data-plane/client/index.ts create mode 100644 services/appview/services/data-plane/client/util.ts rename services/appview/{src => services}/data-plane/server/index.ts (57%) rename services/appview/{src => }/services/indexing.ts (62%) rename services/appview/{src => }/services/plugins/bskyFollow.ts (59%) rename services/appview/{src => }/services/plugins/post.ts (66%) rename services/appview/{src/middleware => services}/takedown-filter.ts (62%) rename services/appview/{src => }/services/takedown.ts (55%) delete mode 100644 services/appview/src/api/admin/takedowns.ts delete mode 100644 services/appview/src/api/com/atproto/admin/getAccountInfos.ts delete mode 100644 services/appview/src/api/com/atproto/admin/getSubjectStatus.ts delete mode 100644 services/appview/src/api/com/atproto/admin/updateSubjectStatus.ts delete mode 100644 services/appview/src/api/com/atproto/identity/resolveHandle.ts delete mode 100644 services/appview/src/api/so/sprk/actor/getPreferences.ts delete mode 100644 services/appview/src/api/so/sprk/actor/putPreferences.ts delete mode 100644 services/appview/src/api/so/sprk/feed/getAuthorFeed.ts delete mode 100644 services/appview/src/api/so/sprk/feed/getPostThread.ts delete mode 100644 services/appview/src/api/so/sprk/feed/getPosts.ts delete mode 100644 services/appview/src/api/so/sprk/graph/getFollowers.ts delete mode 100644 services/appview/src/api/so/sprk/graph/getFollows.ts delete mode 100644 services/appview/src/auth/auth-verifier.ts delete mode 100644 services/appview/src/auth/middleware.ts delete mode 100644 services/appview/src/data-plane/client/index.ts delete mode 100644 services/appview/src/data-plane/client/util.ts delete mode 100644 services/appview/src/env.ts delete mode 100644 services/appview/src/index.ts delete mode 100644 services/appview/src/lexicon/lexicons.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/admin/defs.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/admin/deleteAccount.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/admin/disableAccountInvites.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/admin/disableInviteCodes.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/admin/enableAccountInvites.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/admin/getAccountInfo.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/admin/getAccountInfos.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/admin/getInviteCodes.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/admin/getSubjectStatus.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/admin/searchAccounts.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/admin/sendEmail.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/admin/updateAccountEmail.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/admin/updateAccountHandle.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/admin/updateAccountPassword.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/admin/updateSubjectStatus.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/identity/getRecommendedDidCredentials.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/identity/requestPlcOperationSignature.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/identity/resolveHandle.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/identity/signPlcOperation.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/identity/submitPlcOperation.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/identity/updateHandle.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/label/queryLabels.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/label/subscribeLabels.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/lexicon/schema.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/moderation/createReport.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/moderation/defs.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/repo/applyWrites.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/repo/createRecord.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/repo/defs.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/repo/deleteRecord.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/repo/describeRepo.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/repo/getRecord.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/repo/importRepo.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/repo/listMissingBlobs.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/repo/listRecords.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/repo/putRecord.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/repo/strongRef.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/repo/uploadBlob.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/server/activateAccount.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/server/checkAccountStatus.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/server/confirmEmail.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/server/createAccount.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/server/createAppPassword.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/server/createInviteCode.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/server/createInviteCodes.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/server/createSession.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/server/deactivateAccount.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/server/defs.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/server/deleteAccount.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/server/deleteSession.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/server/describeServer.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/server/getAccountInviteCodes.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/server/getServiceAuth.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/server/getSession.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/server/listAppPasswords.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/server/refreshSession.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/server/requestAccountDelete.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/server/requestEmailConfirmation.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/server/requestEmailUpdate.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/server/requestPasswordReset.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/server/reserveSigningKey.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/server/resetPassword.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/server/revokeAppPassword.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/server/updateEmail.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/sync/getBlob.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/sync/getBlocks.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/sync/getCheckout.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/sync/getHead.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/sync/getLatestCommit.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/sync/getRecord.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/sync/getRepo.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/sync/getRepoStatus.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/sync/listBlobs.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/sync/listRepos.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/sync/listReposByCollection.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/sync/notifyOfUpdate.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/sync/requestCrawl.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/temp/addReservedHandle.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/temp/checkSignupQueue.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/temp/fetchLabels.ts delete mode 100644 services/appview/src/lexicon/types/com/atproto/temp/requestPhoneVerification.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/actor/defs.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/actor/getPreferences.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/actor/getProfile.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/actor/getProfiles.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/actor/getSuggestions.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/actor/profile.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/actor/putPreferences.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/actor/searchActors.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/actor/searchActorsTypeahead.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/embed/defs.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/embed/images.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/embed/video.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/feed/defs.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/feed/describeFeedGenerator.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/feed/generator.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/feed/getActorFeeds.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/feed/getActorLikes.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/feed/getActorLooks.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/feed/getAuthorFeed.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/feed/getFeed.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/feed/getFeedGenerator.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/feed/getFeedGenerators.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/feed/getFeedSkeleton.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/feed/getLikes.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/feed/getListFeed.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/feed/getLooks.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/feed/getPostThread.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/feed/getPosts.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/feed/getQuotes.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/feed/getRepostedBy.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/feed/getSuggestedFeeds.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/feed/getTimeline.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/feed/like.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/feed/look.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/feed/post.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/feed/postgate.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/feed/repost.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/feed/sendInteractions.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/feed/threadgate.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/graph/block.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/graph/defs.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/graph/follow.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/graph/getActorStarterPacks.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/graph/getBlocks.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/graph/getFollowers.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/graph/getFollows.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/graph/getKnownFollowers.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/graph/getList.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/graph/getListBlocks.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/graph/getListMutes.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/graph/getLists.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/graph/getMutes.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/graph/getRelationships.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/graph/getStarterPack.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/graph/getStarterPacks.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/graph/getSuggestedFollowsByActor.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/graph/list.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/graph/listblock.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/graph/listitem.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/graph/muteActor.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/graph/muteActorList.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/graph/muteThread.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/graph/searchStarterPacks.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/graph/starterpack.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/graph/unmuteActor.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/graph/unmuteActorList.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/graph/unmuteThread.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/labeler/defs.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/labeler/getServices.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/labeler/service.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/notification/getUnreadCount.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/notification/listNotifications.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/notification/putPreferences.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/notification/registerPush.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/notification/updateSeen.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/unspecced/defs.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/unspecced/getConfig.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/unspecced/getPopularFeedGenerators.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/unspecced/getSuggestionsSkeleton.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/unspecced/getTaggedSuggestions.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/unspecced/getTrendingTopics.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/unspecced/searchActorsSkeleton.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/unspecced/searchStarterPacksSkeleton.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/video/defs.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/video/getJobStatus.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/video/getUploadLimits.ts delete mode 100644 services/appview/src/lexicon/types/so/sprk/video/uploadVideo.ts delete mode 100644 services/appview/src/utils/express-adapter.ts delete mode 100644 services/appview/tsconfig.json create mode 100644 services/appview/utils/env.ts create mode 100644 services/appview/utils/express-adapter.ts rename services/appview/{src => utils}/id-resolver.ts (52%) rename services/appview/{src => }/utils/post-transformer.ts (50%) rename services/appview/{src => utils}/well-known.ts (50%) diff --git a/.github/workflows/build-appview.yaml b/.github/workflows/build-appview.yaml index fc55fd4..7bccc1f 100644 --- a/.github/workflows/build-appview.yaml +++ b/.github/workflows/build-appview.yaml @@ -4,7 +4,7 @@ name: Build and Push AppView Image on: push: tags: - - 'appview/v*' + - "appview/v*" jobs: build-and-push-appview: diff --git a/.github/workflows/build-cdn.yaml b/.github/workflows/build-cdn.yaml index 236dce3..34dcf18 100644 --- a/.github/workflows/build-cdn.yaml +++ b/.github/workflows/build-cdn.yaml @@ -4,7 +4,7 @@ name: Build and Push CDN Image on: push: tags: - - 'cdn/v*' + - "cdn/v*" jobs: build-and-push-cdn: diff --git a/.github/workflows/build-ingester.yaml b/.github/workflows/build-ingester.yaml index ab7e534..a00f6ae 100644 --- a/.github/workflows/build-ingester.yaml +++ b/.github/workflows/build-ingester.yaml @@ -4,7 +4,7 @@ name: Build and Push Ingester Image on: push: tags: - - 'ingester/v*' + - "ingester/v*" jobs: build-and-push-ingester: diff --git a/deno.json b/deno.json new file mode 100644 index 0000000..15226a6 --- /dev/null +++ b/deno.json @@ -0,0 +1,6 @@ +{ + "workspace": [ + "services/appview" + ], + "unstable": ["sloppy-imports"] +} diff --git a/deno.lock b/deno.lock new file mode 100644 index 0000000..716710a --- /dev/null +++ b/deno.lock @@ -0,0 +1,933 @@ +{ + "version": "5", + "specifiers": { + "jsr:@hono/hono@^4.7.10": "4.7.10", + "jsr:@std/assert@*": "1.0.13", + "jsr:@std/encoding@*": "1.0.10", + "jsr:@std/encoding@1": "1.0.10", + "jsr:@std/internal@^1.0.6": "1.0.8", + "npm:@atproto/api@~0.14.9": "0.14.22", + "npm:@atproto/common@~0.4.8": "0.4.11", + "npm:@atproto/crypto@~0.4.4": "0.4.4", + "npm:@atproto/identity@*": "0.4.8", + "npm:@atproto/identity@~0.4.6": "0.4.8", + "npm:@atproto/lexicon@~0.4.8": "0.4.11", + "npm:@atproto/syntax@~0.3.4": "0.3.4", + "npm:@atproto/xrpc-server@~0.7.12": "0.7.18", + "npm:@types/node@*": "22.15.15", + "npm:dotenv@*": "16.5.0", + "npm:express@*": "4.21.2", + "npm:express@^4.21.2": "4.21.2", + "npm:jose@*": "6.0.11", + "npm:lodash@*": "4.17.21", + "npm:mongoose@^8.12.1": "8.15.1", + "npm:multiformats@^9.9.0": "9.9.0", + "npm:pino@^9.6.0": "9.7.0", + "npm:uint8arrays@*": "5.1.0", + "npm:zod@^3.24.2": "3.25.39" + }, + "jsr": { + "@hono/hono@4.7.10": { + "integrity": "e59029e252af371abe43e8e4f9a115e38974c6bd5972022372bf89f763269cc7" + }, + "@std/assert@1.0.13": { + "integrity": "ae0d31e41919b12c656c742b22522c32fb26ed0cba32975cb0de2a273cb68b29", + "dependencies": [ + "jsr:@std/internal" + ] + }, + "@std/encoding@1.0.10": { + "integrity": "8783c6384a2d13abd5e9e87a7ae0520a30e9f56aeeaa3bdf910a3eaaf5c811a1" + }, + "@std/internal@1.0.8": { + "integrity": "fc66e846d8d38a47cffd274d80d2ca3f0de71040f855783724bb6b87f60891f5" + } + }, + "npm": { + "@atproto/api@0.14.22": { + "integrity": "sha512-ziXPau+sUdFovObSnsoN7JbOmUw1C5e5L28/yXf3P8vbEnSS3HVVGD1jYcscBYY34xQqi4bVDpwMYx/4yRsTuQ==", + "dependencies": [ + "@atproto/common-web", + "@atproto/lexicon", + "@atproto/syntax@0.4.0", + "@atproto/xrpc@0.6.12", + "await-lock", + "multiformats@9.9.0", + "tlds", + "zod" + ] + }, + "@atproto/common-web@0.4.2": { + "integrity": "sha512-vrXwGNoFGogodjQvJDxAeP3QbGtawgZute2ed1XdRO0wMixLk3qewtikZm06H259QDJVu6voKC5mubml+WgQUw==", + "dependencies": [ + "graphemer", + "multiformats@9.9.0", + "uint8arrays@3.0.0", + "zod" + ] + }, + "@atproto/common@0.4.11": { + "integrity": "sha512-Knv0viYXNMfCdIE7jLUiWJKnnMfEwg+vz2epJQi8WOjqtqCFb3W/3Jn72ZiuovIfpdm13MaOiny6w2NErUQC6g==", + "dependencies": [ + "@atproto/common-web", + "@ipld/dag-cbor", + "cbor-x", + "iso-datestring-validator", + "multiformats@9.9.0", + "pino@8.21.0" + ] + }, + "@atproto/crypto@0.4.4": { + "integrity": "sha512-Yq9+crJ7WQl7sxStVpHgie5Z51R05etaK9DLWYG/7bR5T4bhdcIgF6IfklLShtZwLYdVVj+K15s0BqW9a8PSDA==", + "dependencies": [ + "@noble/curves", + "@noble/hashes", + "uint8arrays@3.0.0" + ] + }, + "@atproto/identity@0.4.8": { + "integrity": "sha512-Z0sLnJ87SeNdAifT+rqpgE1Rc3layMMW25gfWNo4u40RGuRODbdfAZlTwBSU2r+Vk45hU+iE+xeQspfednCEnA==", + "dependencies": [ + "@atproto/common-web", + "@atproto/crypto" + ] + }, + "@atproto/lexicon@0.4.11": { + "integrity": "sha512-btefdnvNz2Ao2I+qbmj0F06HC8IlrM/IBz6qOBS50r0S6uDf5tOO+Mv2tSVdimFkdzyDdLtBI1sV36ONxz2cOw==", + "dependencies": [ + "@atproto/common-web", + "@atproto/syntax@0.4.0", + "iso-datestring-validator", + "multiformats@9.9.0", + "zod" + ] + }, + "@atproto/syntax@0.3.4": { + "integrity": "sha512-8CNmi5DipOLaVeSMPggMe7FCksVag0aO6XZy9WflbduTKM4dFZVCs4686UeMLfGRXX+X966XgwECHoLYrovMMg==" + }, + "@atproto/syntax@0.4.0": { + "integrity": "sha512-b9y5ceHS8YKOfP3mdKmwAx5yVj9294UN7FG2XzP6V5aKUdFazEYRnR9m5n5ZQFKa3GNvz7de9guZCJ/sUTcOAA==" + }, + "@atproto/xrpc-server@0.7.18": { + "integrity": "sha512-kjlAsI+UNbbm6AK3Y5Hb4BJ7VQHNKiYYu2kX5vhZJZHO8qfO40GPYYb/2TknZV8IG6fDPBQhUpcDRolI86sgag==", + "dependencies": [ + "@atproto/common", + "@atproto/crypto", + "@atproto/lexicon", + "@atproto/xrpc@0.7.0", + "cbor-x", + "express", + "http-errors", + "mime-types", + "rate-limiter-flexible", + "uint8arrays@3.0.0", + "ws", + "zod" + ] + }, + "@atproto/xrpc@0.6.12": { + "integrity": "sha512-Ut3iISNLujlmY9Gu8sNU+SPDJDvqlVzWddU8qUr0Yae5oD4SguaUFjjhireMGhQ3M5E0KljQgDbTmnBo1kIZ3w==", + "dependencies": [ + "@atproto/lexicon", + "zod" + ] + }, + "@atproto/xrpc@0.7.0": { + "integrity": "sha512-SfhP9dGx2qclaScFDb58Jnrmim5nk4geZXCqg6sB0I/KZhZEkr9iIx1hLCp+sxkIfEsmEJjeWO4B0rjUIJW5cw==", + "dependencies": [ + "@atproto/lexicon", + "zod" + ] + }, + "@cbor-extract/cbor-extract-darwin-arm64@2.2.0": { + "integrity": "sha512-P7swiOAdF7aSi0H+tHtHtr6zrpF3aAq/W9FXx5HektRvLTM2O89xCyXF3pk7pLc7QpaY7AoaE8UowVf9QBdh3w==", + "os": ["darwin"], + "cpu": ["arm64"] + }, + "@cbor-extract/cbor-extract-darwin-x64@2.2.0": { + "integrity": "sha512-1liF6fgowph0JxBbYnAS7ZlqNYLf000Qnj4KjqPNW4GViKrEql2MgZnAsExhY9LSy8dnvA4C0qHEBgPrll0z0w==", + "os": ["darwin"], + "cpu": ["x64"] + }, + "@cbor-extract/cbor-extract-linux-arm64@2.2.0": { + "integrity": "sha512-rQvhNmDuhjTVXSPFLolmQ47/ydGOFXtbR7+wgkSY0bdOxCFept1hvg59uiLPT2fVDuJFuEy16EImo5tE2x3RsQ==", + "os": ["linux"], + "cpu": ["arm64"] + }, + "@cbor-extract/cbor-extract-linux-arm@2.2.0": { + "integrity": "sha512-QeBcBXk964zOytiedMPQNZr7sg0TNavZeuUCD6ON4vEOU/25+pLhNN6EDIKJ9VLTKaZ7K7EaAriyYQ1NQ05s/Q==", + "os": ["linux"], + "cpu": ["arm"] + }, + "@cbor-extract/cbor-extract-linux-x64@2.2.0": { + "integrity": "sha512-cWLAWtT3kNLHSvP4RKDzSTX9o0wvQEEAj4SKvhWuOVZxiDAeQazr9A+PSiRILK1VYMLeDml89ohxCnUNQNQNCw==", + "os": ["linux"], + "cpu": ["x64"] + }, + "@cbor-extract/cbor-extract-win32-x64@2.2.0": { + "integrity": "sha512-l2M+Z8DO2vbvADOBNLbbh9y5ST1RY5sqkWOg/58GkUPBYou/cuNZ68SGQ644f1CvZ8kcOxyZtw06+dxWHIoN/w==", + "os": ["win32"], + "cpu": ["x64"] + }, + "@ipld/dag-cbor@7.0.3": { + "integrity": "sha512-1VVh2huHsuohdXC1bGJNE8WR72slZ9XE2T3wbBBq31dm7ZBatmKLLxrB+XAqafxfRFjv08RZmj/W/ZqaM13AuA==", + "dependencies": [ + "cborg", + "multiformats@9.9.0" + ] + }, + "@mongodb-js/saslprep@1.2.2": { + "integrity": "sha512-EB0O3SCSNRUFk66iRCpI+cXzIjdswfCs7F6nOC3RAGJ7xr5YhaicvsRwJ9eyzYvYRlCSDUO/c7g4yNulxKC1WA==", + "dependencies": [ + "sparse-bitfield" + ] + }, + "@noble/curves@1.9.1": { + "integrity": "sha512-k11yZxZg+t+gWvBbIswW0yoJlu8cHOC7dhunwOzoWH/mXGBiYyR4YY6hAEK/3EUs4UpB8la1RfdRpeGsFHkWsA==", + "dependencies": [ + "@noble/hashes" + ] + }, + "@noble/hashes@1.8.0": { + "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==" + }, + "@types/node@22.15.15": { + "integrity": "sha512-R5muMcZob3/Jjchn5LcO8jdKwSCbzqmPB6ruBxMcf9kbxtniZHP327s6C37iOfuw8mbKK3cAQa7sEl7afLrQ8A==", + "dependencies": [ + "undici-types" + ] + }, + "@types/webidl-conversions@7.0.3": { + "integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==" + }, + "@types/whatwg-url@11.0.5": { + "integrity": "sha512-coYR071JRaHa+xoEvvYqvnIHaVqaYrLPbsufM9BF63HkwI5Lgmy2QR8Q5K/lYDYo5AK82wOvSOS0UsLTpTG7uQ==", + "dependencies": [ + "@types/webidl-conversions" + ] + }, + "abort-controller@3.0.0": { + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "dependencies": [ + "event-target-shim" + ] + }, + "accepts@1.3.8": { + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dependencies": [ + "mime-types", + "negotiator" + ] + }, + "array-flatten@1.1.1": { + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + }, + "atomic-sleep@1.0.0": { + "integrity": "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==" + }, + "await-lock@2.2.2": { + "integrity": "sha512-aDczADvlvTGajTDjcjpJMqRkOF6Qdz3YbPZm/PyW6tKPkx2hlYBzxMhEywM/tU72HrVZjgl5VCdRuMlA7pZ8Gw==" + }, + "base64-js@1.5.1": { + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + }, + "body-parser@1.20.3": { + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", + "dependencies": [ + "bytes", + "content-type", + "debug@2.6.9", + "depd", + "destroy", + "http-errors", + "iconv-lite", + "on-finished", + "qs", + "raw-body", + "type-is", + "unpipe" + ] + }, + "bson@6.10.3": { + "integrity": "sha512-MTxGsqgYTwfshYWTRdmZRC+M7FnG1b4y7RO7p2k3X24Wq0yv1m77Wsj0BzlPzd/IowgESfsruQCUToa7vbOpPQ==" + }, + "buffer@6.0.3": { + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "dependencies": [ + "base64-js", + "ieee754" + ] + }, + "bytes@3.1.2": { + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" + }, + "call-bind-apply-helpers@1.0.2": { + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dependencies": [ + "es-errors", + "function-bind" + ] + }, + "call-bound@1.0.4": { + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dependencies": [ + "call-bind-apply-helpers", + "get-intrinsic" + ] + }, + "cbor-extract@2.2.0": { + "integrity": "sha512-Ig1zM66BjLfTXpNgKpvBePq271BPOvu8MR0Jl080yG7Jsl+wAZunfrwiwA+9ruzm/WEdIV5QF/bjDZTqyAIVHA==", + "dependencies": [ + "node-gyp-build-optional-packages" + ], + "optionalDependencies": [ + "@cbor-extract/cbor-extract-darwin-arm64", + "@cbor-extract/cbor-extract-darwin-x64", + "@cbor-extract/cbor-extract-linux-arm", + "@cbor-extract/cbor-extract-linux-arm64", + "@cbor-extract/cbor-extract-linux-x64", + "@cbor-extract/cbor-extract-win32-x64" + ], + "scripts": true, + "bin": true + }, + "cbor-x@1.6.0": { + "integrity": "sha512-0kareyRwHSkL6ws5VXHEf8uY1liitysCVJjlmhaLG+IXLqhSaOO+t63coaso7yjwEzWZzLy8fJo06gZDVQM9Qg==", + "optionalDependencies": [ + "cbor-extract" + ] + }, + "cborg@1.10.2": { + "integrity": "sha512-b3tFPA9pUr2zCUiCfRd2+wok2/LBSNUMKOuRRok+WlvvAgEt/PlbgPTsZUcwCOs53IJvLgTp0eotwtosE6njug==", + "bin": true + }, + "content-disposition@0.5.4": { + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dependencies": [ + "safe-buffer" + ] + }, + "content-type@1.0.5": { + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==" + }, + "cookie-signature@1.0.6": { + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + }, + "cookie@0.7.1": { + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==" + }, + "debug@2.6.9": { + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": [ + "ms@2.0.0" + ] + }, + "debug@4.4.1": { + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "dependencies": [ + "ms@2.1.3" + ] + }, + "depd@2.0.0": { + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + }, + "destroy@1.2.0": { + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==" + }, + "detect-libc@2.0.4": { + "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==" + }, + "dotenv@16.5.0": { + "integrity": "sha512-m/C+AwOAr9/W1UOIZUo232ejMNnJAJtYQjUbHoNTBNTJSvqzzDh7vnrei3o3r3m9blf6ZoDkvcw0VmozNRFJxg==" + }, + "dunder-proto@1.0.1": { + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dependencies": [ + "call-bind-apply-helpers", + "es-errors", + "gopd" + ] + }, + "ee-first@1.1.1": { + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + }, + "encodeurl@1.0.2": { + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==" + }, + "encodeurl@2.0.0": { + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==" + }, + "es-define-property@1.0.1": { + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==" + }, + "es-errors@1.3.0": { + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==" + }, + "es-object-atoms@1.1.1": { + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dependencies": [ + "es-errors" + ] + }, + "escape-html@1.0.3": { + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + }, + "etag@1.8.1": { + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==" + }, + "event-target-shim@5.0.1": { + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==" + }, + "events@3.3.0": { + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==" + }, + "express@4.21.2": { + "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", + "dependencies": [ + "accepts", + "array-flatten", + "body-parser", + "content-disposition", + "content-type", + "cookie", + "cookie-signature", + "debug@2.6.9", + "depd", + "encodeurl@2.0.0", + "escape-html", + "etag", + "finalhandler", + "fresh", + "http-errors", + "merge-descriptors", + "methods", + "on-finished", + "parseurl", + "path-to-regexp", + "proxy-addr", + "qs", + "range-parser", + "safe-buffer", + "send", + "serve-static", + "setprototypeof", + "statuses", + "type-is", + "utils-merge", + "vary" + ] + }, + "fast-redact@3.5.0": { + "integrity": "sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==" + }, + "finalhandler@1.3.1": { + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", + "dependencies": [ + "debug@2.6.9", + "encodeurl@2.0.0", + "escape-html", + "on-finished", + "parseurl", + "statuses", + "unpipe" + ] + }, + "forwarded@0.2.0": { + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" + }, + "fresh@0.5.2": { + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==" + }, + "function-bind@1.1.2": { + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" + }, + "get-intrinsic@1.3.0": { + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dependencies": [ + "call-bind-apply-helpers", + "es-define-property", + "es-errors", + "es-object-atoms", + "function-bind", + "get-proto", + "gopd", + "has-symbols", + "hasown", + "math-intrinsics" + ] + }, + "get-proto@1.0.1": { + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dependencies": [ + "dunder-proto", + "es-object-atoms" + ] + }, + "gopd@1.2.0": { + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==" + }, + "graphemer@1.4.0": { + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==" + }, + "has-symbols@1.1.0": { + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==" + }, + "hasown@2.0.2": { + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dependencies": [ + "function-bind" + ] + }, + "http-errors@2.0.0": { + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dependencies": [ + "depd", + "inherits", + "setprototypeof", + "statuses", + "toidentifier" + ] + }, + "iconv-lite@0.4.24": { + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": [ + "safer-buffer" + ] + }, + "ieee754@1.2.1": { + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, + "inherits@2.0.4": { + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "ipaddr.js@1.9.1": { + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" + }, + "iso-datestring-validator@2.2.2": { + "integrity": "sha512-yLEMkBbLZTlVQqOnQ4FiMujR6T4DEcCb1xizmvXS+OxuhwcbtynoosRzdMA69zZCShCNAbi+gJ71FxZBBXx1SA==" + }, + "jose@6.0.11": { + "integrity": "sha512-QxG7EaliDARm1O1S8BGakqncGT9s25bKL1WSf6/oa17Tkqwi8D2ZNglqCF+DsYF88/rV66Q/Q2mFAy697E1DUg==" + }, + "kareem@2.6.3": { + "integrity": "sha512-C3iHfuGUXK2u8/ipq9LfjFfXFxAZMQJJq7vLS45r3D9Y2xQ/m4S8zaR4zMLFWh9AsNPXmcFfUDhTEO8UIC/V6Q==" + }, + "lodash@4.17.21": { + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "math-intrinsics@1.1.0": { + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==" + }, + "media-typer@0.3.0": { + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==" + }, + "memory-pager@1.5.0": { + "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==" + }, + "merge-descriptors@1.0.3": { + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==" + }, + "methods@1.1.2": { + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==" + }, + "mime-db@1.52.0": { + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" + }, + "mime-types@2.1.35": { + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": [ + "mime-db" + ] + }, + "mime@1.6.0": { + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": true + }, + "mongodb-connection-string-url@3.0.2": { + "integrity": "sha512-rMO7CGo/9BFwyZABcKAWL8UJwH/Kc2x0g72uhDWzG48URRax5TCIcJ7Rc3RZqffZzO/Gwff/jyKwCU9TN8gehA==", + "dependencies": [ + "@types/whatwg-url", + "whatwg-url" + ] + }, + "mongodb@6.16.0": { + "integrity": "sha512-D1PNcdT0y4Grhou5Zi/qgipZOYeWrhLEpk33n3nm6LGtz61jvO88WlrWCK/bigMjpnOdAUKKQwsGIl0NtWMyYw==", + "dependencies": [ + "@mongodb-js/saslprep", + "bson", + "mongodb-connection-string-url" + ] + }, + "mongoose@8.15.1": { + "integrity": "sha512-RhQ4DzmBi5BNGcS0w4u1vdMRIKcteXTCNzDt1j7XRcdWYBz1MjMjulBhPaeC5jBCHOD1yinuOFTTSOWLLGexWw==", + "dependencies": [ + "bson", + "kareem", + "mongodb", + "mpath", + "mquery", + "ms@2.1.3", + "sift" + ] + }, + "mpath@0.9.0": { + "integrity": "sha512-ikJRQTk8hw5DEoFVxHG1Gn9T/xcjtdnOKIU1JTmGjZZlg9LST2mBLmcX3/ICIbgJydT2GOc15RnNy5mHmzfSew==" + }, + "mquery@5.0.0": { + "integrity": "sha512-iQMncpmEK8R8ncT8HJGsGc9Dsp8xcgYMVSbs5jgnm1lFHTZqMJTUWTDx1LBO8+mK3tPNZWFLBghQEIOULSTHZg==", + "dependencies": [ + "debug@4.4.1" + ] + }, + "ms@2.0.0": { + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "ms@2.1.3": { + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "multiformats@13.3.6": { + "integrity": "sha512-yakbt9cPYj8d3vi/8o/XWm61MrOILo7fsTL0qxNx6zS0Nso6K5JqqS2WV7vK/KSuDBvrW3KfCwAdAgarAgOmww==" + }, + "multiformats@9.9.0": { + "integrity": "sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg==" + }, + "negotiator@0.6.3": { + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" + }, + "node-gyp-build-optional-packages@5.1.1": { + "integrity": "sha512-+P72GAjVAbTxjjwUmwjVrqrdZROD4nf8KgpBoDxqXXTiYZZt/ud60dE5yvCSr9lRO8e8yv6kgJIC0K0PfZFVQw==", + "dependencies": [ + "detect-libc" + ], + "bin": true + }, + "object-inspect@1.13.4": { + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==" + }, + "on-exit-leak-free@2.1.2": { + "integrity": "sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==" + }, + "on-finished@2.4.1": { + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dependencies": [ + "ee-first" + ] + }, + "parseurl@1.3.3": { + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" + }, + "path-to-regexp@0.1.12": { + "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==" + }, + "pino-abstract-transport@1.2.0": { + "integrity": "sha512-Guhh8EZfPCfH+PMXAb6rKOjGQEoy0xlAIn+irODG5kgfYV+BQ0rGYYWTIel3P5mmyXqkYkPmdIkywsn6QKUR1Q==", + "dependencies": [ + "readable-stream", + "split2" + ] + }, + "pino-abstract-transport@2.0.0": { + "integrity": "sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw==", + "dependencies": [ + "split2" + ] + }, + "pino-std-serializers@6.2.2": { + "integrity": "sha512-cHjPPsE+vhj/tnhCy/wiMh3M3z3h/j15zHQX+S9GkTBgqJuTuJzYJ4gUyACLhDaJ7kk9ba9iRDmbH2tJU03OiA==" + }, + "pino-std-serializers@7.0.0": { + "integrity": "sha512-e906FRY0+tV27iq4juKzSYPbUj2do2X2JX4EzSca1631EB2QJQUqGbDuERal7LCtOpxl6x3+nvo9NPZcmjkiFA==" + }, + "pino@8.21.0": { + "integrity": "sha512-ip4qdzjkAyDDZklUaZkcRFb2iA118H9SgRh8yzTkSQK8HilsOJF7rSY8HoW5+I0M46AZgX/pxbprf2vvzQCE0Q==", + "dependencies": [ + "atomic-sleep", + "fast-redact", + "on-exit-leak-free", + "pino-abstract-transport@1.2.0", + "pino-std-serializers@6.2.2", + "process-warning@3.0.0", + "quick-format-unescaped", + "real-require", + "safe-stable-stringify", + "sonic-boom@3.8.1", + "thread-stream@2.7.0" + ], + "bin": true + }, + "pino@9.7.0": { + "integrity": "sha512-vnMCM6xZTb1WDmLvtG2lE/2p+t9hDEIvTWJsu6FejkE62vB7gDhvzrpFR4Cw2to+9JNQxVnkAKVPA1KPB98vWg==", + "dependencies": [ + "atomic-sleep", + "fast-redact", + "on-exit-leak-free", + "pino-abstract-transport@2.0.0", + "pino-std-serializers@7.0.0", + "process-warning@5.0.0", + "quick-format-unescaped", + "real-require", + "safe-stable-stringify", + "sonic-boom@4.2.0", + "thread-stream@3.1.0" + ], + "bin": true + }, + "process-warning@3.0.0": { + "integrity": "sha512-mqn0kFRl0EoqhnL0GQ0veqFHyIN1yig9RHh/InzORTUiZHFRAur+aMtRkELNwGs9aNwKS6tg/An4NYBPGwvtzQ==" + }, + "process-warning@5.0.0": { + "integrity": "sha512-a39t9ApHNx2L4+HBnQKqxxHNs1r7KF+Intd8Q/g1bUh6q0WIp9voPXJ/x0j+ZL45KF1pJd9+q2jLIRMfvEshkA==" + }, + "process@0.11.10": { + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==" + }, + "proxy-addr@2.0.7": { + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dependencies": [ + "forwarded", + "ipaddr.js" + ] + }, + "punycode@2.3.1": { + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==" + }, + "qs@6.13.0": { + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "dependencies": [ + "side-channel" + ] + }, + "quick-format-unescaped@4.0.4": { + "integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==" + }, + "range-parser@1.2.1": { + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" + }, + "rate-limiter-flexible@2.4.2": { + "integrity": "sha512-rMATGGOdO1suFyf/mI5LYhts71g1sbdhmd6YvdiXO2gJnd42Tt6QS4JUKJKSWVVkMtBacm6l40FR7Trjo6Iruw==" + }, + "raw-body@2.5.2": { + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "dependencies": [ + "bytes", + "http-errors", + "iconv-lite", + "unpipe" + ] + }, + "readable-stream@4.7.0": { + "integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==", + "dependencies": [ + "abort-controller", + "buffer", + "events", + "process", + "string_decoder" + ] + }, + "real-require@0.2.0": { + "integrity": "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==" + }, + "safe-buffer@5.2.1": { + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, + "safe-stable-stringify@2.5.0": { + "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==" + }, + "safer-buffer@2.1.2": { + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "send@0.19.0": { + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", + "dependencies": [ + "debug@2.6.9", + "depd", + "destroy", + "encodeurl@1.0.2", + "escape-html", + "etag", + "fresh", + "http-errors", + "mime", + "ms@2.1.3", + "on-finished", + "range-parser", + "statuses" + ] + }, + "serve-static@1.16.2": { + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", + "dependencies": [ + "encodeurl@2.0.0", + "escape-html", + "parseurl", + "send" + ] + }, + "setprototypeof@1.2.0": { + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "side-channel-list@1.0.0": { + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dependencies": [ + "es-errors", + "object-inspect" + ] + }, + "side-channel-map@1.0.1": { + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dependencies": [ + "call-bound", + "es-errors", + "get-intrinsic", + "object-inspect" + ] + }, + "side-channel-weakmap@1.0.2": { + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dependencies": [ + "call-bound", + "es-errors", + "get-intrinsic", + "object-inspect", + "side-channel-map" + ] + }, + "side-channel@1.1.0": { + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "dependencies": [ + "es-errors", + "object-inspect", + "side-channel-list", + "side-channel-map", + "side-channel-weakmap" + ] + }, + "sift@17.1.3": { + "integrity": "sha512-Rtlj66/b0ICeFzYTuNvX/EF1igRbbnGSvEyT79McoZa/DeGhMyC5pWKOEsZKnpkqtSeovd5FL/bjHWC3CIIvCQ==" + }, + "sonic-boom@3.8.1": { + "integrity": "sha512-y4Z8LCDBuum+PBP3lSV7RHrXscqksve/bi0as7mhwVnBW+/wUqKT/2Kb7um8yqcFy0duYbbPxzt89Zy2nOCaxg==", + "dependencies": [ + "atomic-sleep" + ] + }, + "sonic-boom@4.2.0": { + "integrity": "sha512-INb7TM37/mAcsGmc9hyyI6+QR3rR1zVRu36B0NeGXKnOOLiZOfER5SA+N7X7k3yUYRzLWafduTDvJAfDswwEww==", + "dependencies": [ + "atomic-sleep" + ] + }, + "sparse-bitfield@3.0.3": { + "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", + "dependencies": [ + "memory-pager" + ] + }, + "split2@4.2.0": { + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==" + }, + "statuses@2.0.1": { + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" + }, + "string_decoder@1.3.0": { + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": [ + "safe-buffer" + ] + }, + "thread-stream@2.7.0": { + "integrity": "sha512-qQiRWsU/wvNolI6tbbCKd9iKaTnCXsTwVxhhKM6nctPdujTyztjlbUkUTUymidWcMnZ5pWR0ej4a0tjsW021vw==", + "dependencies": [ + "real-require" + ] + }, + "thread-stream@3.1.0": { + "integrity": "sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==", + "dependencies": [ + "real-require" + ] + }, + "tlds@1.259.0": { + "integrity": "sha512-AldGGlDP0PNgwppe2quAvuBl18UcjuNtOnDuUkqhd6ipPqrYYBt3aTxK1QTsBVknk97lS2JcafWMghjGWFtunw==", + "bin": true + }, + "toidentifier@1.0.1": { + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" + }, + "tr46@5.1.1": { + "integrity": "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==", + "dependencies": [ + "punycode" + ] + }, + "type-is@1.6.18": { + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dependencies": [ + "media-typer", + "mime-types" + ] + }, + "uint8arrays@3.0.0": { + "integrity": "sha512-HRCx0q6O9Bfbp+HHSfQQKD7wU70+lydKVt4EghkdOvlK/NlrF90z+eXV34mUd48rNvVJXwkrMSPpCATkct8fJA==", + "dependencies": [ + "multiformats@9.9.0" + ] + }, + "uint8arrays@5.1.0": { + "integrity": "sha512-vA6nFepEmlSKkMBnLBaUMVvAC4G3CTmO58C12y4sq6WPDOR7mOFYOi7GlrQ4djeSbP6JG9Pv9tJDM97PedRSww==", + "dependencies": [ + "multiformats@13.3.6" + ] + }, + "undici-types@6.21.0": { + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==" + }, + "unpipe@1.0.0": { + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==" + }, + "utils-merge@1.0.1": { + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==" + }, + "vary@1.1.2": { + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==" + }, + "webidl-conversions@7.0.0": { + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==" + }, + "whatwg-url@14.2.0": { + "integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==", + "dependencies": [ + "tr46", + "webidl-conversions" + ] + }, + "ws@8.18.2": { + "integrity": "sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ==" + }, + "zod@3.25.39": { + "integrity": "sha512-yrva2T2x4R+FMFTPBVD/YPS7ct8njqjnV93zNx/MlwqLAxcnxwRGbXWyWF63/nErl3rdRd8KARObon7BiWzabQ==" + } + }, + "workspace": { + "members": { + "services/appview": { + "dependencies": [ + "jsr:@hono/hono@^4.7.10", + "jsr:@std/encoding@1", + "npm:@atproto/api@~0.14.9", + "npm:@atproto/common@~0.4.8", + "npm:@atproto/crypto@~0.4.4", + "npm:@atproto/identity@~0.4.6", + "npm:@atproto/lexicon@~0.4.8", + "npm:@atproto/syntax@~0.3.4", + "npm:@atproto/xrpc-server@~0.7.12", + "npm:express@^4.21.2", + "npm:mongoose@^8.12.1", + "npm:multiformats@^9.9.0", + "npm:pino@^9.6.0" + ] + } + } + } +} diff --git a/lexicons/so/sprk/actor/defs.json b/lexicons/so/sprk/actor/defs.json index 6fca201..c1dd7df 100644 --- a/lexicons/so/sprk/actor/defs.json +++ b/lexicons/so/sprk/actor/defs.json @@ -307,7 +307,14 @@ "sort": { "type": "string", "description": "Sorting mode for threads.", - "knownValues": ["oldest", "newest", "most-likes", "most-looks", "random", "hotness"] + "knownValues": [ + "oldest", + "newest", + "most-likes", + "most-looks", + "random", + "hotness" + ] }, "prioritizeFollowedUsers": { "type": "boolean", diff --git a/lexicons/so/sprk/feed/audio.json b/lexicons/so/sprk/feed/audio.json index ed86ac3..789e2e3 100644 --- a/lexicons/so/sprk/feed/audio.json +++ b/lexicons/so/sprk/feed/audio.json @@ -41,4 +41,4 @@ } } } -} \ No newline at end of file +} diff --git a/lexicons/so/sprk/feed/music.json b/lexicons/so/sprk/feed/music.json index 44751cf..0e837be 100644 --- a/lexicons/so/sprk/feed/music.json +++ b/lexicons/so/sprk/feed/music.json @@ -82,4 +82,4 @@ } } } -} \ No newline at end of file +} diff --git a/services/appview/.env.example b/services/appview/.env.example deleted file mode 100644 index 6604601..0000000 --- a/services/appview/.env.example +++ /dev/null @@ -1,17 +0,0 @@ -# Database -DB_HOST=localhost -DB_PORT=27017 -DB_NAME=dev -DB_USER=mongo -DB_PASSWORD=mongo - -# Server -HOST=0.0.0.0 -NODE_ENV=development -PORT=3000 -PUBLIC_URL=http://localhost:3000 -SERVICE_DID=did:web:localhost - -# Keys, generate these with openssl ecparam --name secp256k1 --genkey --noout --outform DER | tail --bytes=+8 | head --bytes=32 | xxd --plain --cols 32 -APPVIEW_K256_PRIVATE_KEY_HEX=keyhex -ADMIN_PASSWORD=password diff --git a/services/appview/Dockerfile b/services/appview/Dockerfile index ec76c54..6642830 100644 --- a/services/appview/Dockerfile +++ b/services/appview/Dockerfile @@ -1,30 +1,19 @@ -FROM node:20-alpine AS builder +FROM denoland/deno:alpine-2.3.5 AS builder WORKDIR /app -COPY package.json pnpm-lock.yaml ./ -RUN corepack enable && corepack prepare --activate - -RUN pnpm install --frozen-lockfile - COPY . . -RUN pnpm run build +RUN deno cache main.ts -FROM node:20-alpine AS production - -WORKDIR /app +FROM denoland/deno:alpine-2.3.5 AS production ENV NODE_ENV=production -COPY package.json pnpm-lock.yaml ./ - -RUN corepack enable && corepack prepare --activate - -RUN pnpm install --frozen-lockfile --prod +WORKDIR /app -COPY --from=builder /app/dist ./dist +COPY --from=builder /app . EXPOSE 3000 -CMD ["node", "dist/index.js"] +CMD ["deno", "task", "start"] diff --git a/services/appview/Dockerfile.dev b/services/appview/Dockerfile.dev index 79082bd..0805d4d 100644 --- a/services/appview/Dockerfile.dev +++ b/services/appview/Dockerfile.dev @@ -1,15 +1,11 @@ -FROM node:latest +FROM denoland/deno:latest WORKDIR /app -RUN corepack enable && corepack prepare pnpm@latest --activate - -COPY package.json pnpm-lock.yaml ./ - -RUN pnpm install --frozen-lockfile - COPY . . EXPOSE 3000 -CMD ["pnpm", "run", "dev"] \ No newline at end of file +RUN deno install + +CMD ["deno", "task", "dev"] \ No newline at end of file diff --git a/services/appview/README.md b/services/appview/README.md index 797f1ec..c51842e 100644 --- a/services/appview/README.md +++ b/services/appview/README.md @@ -2,20 +2,36 @@ ## Running -To run for development, first install dependencies. -`pnpm install` +To run with Docker Compose (includes database and appview): +`deno task docker-dev`. This will start both the database and appview services +in Docker containers. -To run in Docker, first build the image: -`docker build -t appview .` +For development without Docker, set up the .env file by following the +instructions down below, then start the development server: `deno task dev` -Then run the container: -`pnpm docker-dev` - -For development without Docker, copy the .env.example file into a .env file and follow the instructions to generate a key, then start the development server: -`pnpm dev` - -This will start the server in development mode with hot reloading enabled. +Both methods will start the server in development mode with hot reloading +enabled available at `http://localhost:4000`. ## Environment Variables -See the `.env.example` file in the project root to see what environment variables are required for the application to run properly. This file contains all the necessary configuration options with example values. +.env setup: + +``` +# Database +DB_HOST=localhost +DB_PORT=27017 +DB_NAME=dev +DB_USER=mongo +DB_PASSWORD=mongo + +# Server +HOST=0.0.0.0 +NODE_ENV=development +PORT=4000 +PUBLIC_URL=http://localhost:3000 +SERVICE_DID=did:web:localhost + +# Keys, generate these with openssl ecparam --name secp256k1 --genkey --noout --outform DER | tail --bytes=+8 | head --bytes=32 | xxd --plain --cols 32 +APPVIEW_K256_PRIVATE_KEY_HEX=keyhex +ADMIN_PASSWORD=password +``` diff --git a/services/appview/api/com/atproto/admin/getAccountInfos.ts b/services/appview/api/com/atproto/admin/getAccountInfos.ts new file mode 100644 index 0000000..bab7c2c --- /dev/null +++ b/services/appview/api/com/atproto/admin/getAccountInfos.ts @@ -0,0 +1,47 @@ +import { AppContext } from "../../../../main.ts"; +import { mapDefined } from "@atproto/common"; +import { INVALID_HANDLE } from "@atproto/syntax"; +import { Server } from "../../../../lexicon/index.ts"; +import { AuthRequiredError } from "@atproto/xrpc-server"; + +export default function (server: Server, ctx: AppContext) { + server.com.atproto.admin.getAccountInfos({ + auth: ctx.authVerifier.optionalStandardOrRole, + handler: async ({ params, auth }) => { + const { dids } = params; + + const { includeTakedowns } = ctx.authVerifier.parseCreds(auth); + if (!includeTakedowns) { + throw new AuthRequiredError("Requires admin privileges"); + } + + const infos = await Promise.all(mapDefined(dids, async (did) => { + const info = await ctx.db.models.Actor.findOne({ did }); + if (!info) return; + const profileRecord = await ctx.db.models.Profile.findOne({ + authorDid: did, + }); + const profileObj = profileRecord + ? { ...profileRecord.toJSON(), _id: undefined, __v: undefined } + : undefined; + + return { + $type: "com.atproto.admin.defs#accountView" as const, + did, + handle: info.handle ?? INVALID_HANDLE, + relatedRecords: profileObj ? [profileObj] : undefined, + indexedAt: info.indexedAt, + }; + })); + + return { + encoding: "application/json", + body: { + infos: infos.filter((info): info is NonNullable => + info != null + ), + }, + }; + }, + }); +} diff --git a/services/appview/api/com/atproto/admin/getSubjectStatus.ts b/services/appview/api/com/atproto/admin/getSubjectStatus.ts new file mode 100644 index 0000000..f8ff219 --- /dev/null +++ b/services/appview/api/com/atproto/admin/getSubjectStatus.ts @@ -0,0 +1,94 @@ +import { AppContext } from "../../../../main.ts"; +import { Server } from "../../../../lexicon/index.ts"; +import { AuthRequiredError, XRPCError } from "@atproto/xrpc-server"; + +export default function (server: Server, ctx: AppContext) { + server.com.atproto.admin.getSubjectStatus({ + auth: ctx.authVerifier.optionalStandardOrRole, + handler: async ({ params, auth }) => { + const { did, uri, blob } = params; + const { includeTakedowns } = ctx.authVerifier.parseCreds(auth); + if (!includeTakedowns) { + throw new AuthRequiredError("Requires admin privileges"); + } + + let subject: { $type: string } & Record; + let takedown: { applied: boolean; ref: string | undefined } | undefined; + + if (did) { + const actor = await ctx.db.models.Actor.findOne({ did }); + const repoTakedown = await ctx.db.models.RepoTakedown.findOne({ + subjectDid: did, + }); + if (!actor) { + throw new XRPCError(404, "NotFound", "Actor not found"); + } + subject = { + $type: "com.atproto.admin.defs#repoRef", + did: actor.did, + }; + if (repoTakedown) { + takedown = { + applied: repoTakedown.applied, + ref: repoTakedown.ref || undefined, + }; + } + } else if (uri) { + const record = (await ctx.db.models.Profile.findOne({ uri })) ?? + (await ctx.db.models.Post.findOne({ uri })) ?? + (await ctx.db.models.Audio.findOne({ uri })); + const recordTakedown = await ctx.db.models.Takedown.findOne({ + subjectUri: uri, + }); + if (!record) { + throw new XRPCError(404, "NotFound", "Record not found"); + } + subject = { + $type: "com.atproto.admin.defs#recordRef", + uri: record.uri, + cid: record.cid, + }; + if (recordTakedown) { + takedown = { + applied: recordTakedown.applied, + ref: recordTakedown.ref || undefined, + }; + } + } else if (blob) { + const blobRecord = (await ctx.db.models.Profile.findOne({ blob })) ?? + (await ctx.db.models.Post.findOne({ blob })) ?? + (await ctx.db.models.Audio.findOne({ blob })); + if (!blobRecord) { + throw new XRPCError(404, "NotFound", "Blob record not found"); + } + subject = { + $type: "com.atproto.admin.defs#repoBlobRef", + did: blobRecord.authorDid, + cid: blobRecord.cid, + recordUri: blobRecord.uri, + }; + const blobTakedown = await ctx.db.models.BlobTakedown.findOne({ + subjectDid: blobRecord.authorDid, + subjectCid: blobRecord.cid, + }); + if (blobTakedown) { + takedown = { + applied: blobTakedown.applied, + ref: blobTakedown.ref || undefined, + }; + } + } else { + throw new XRPCError( + 400, + "InvalidRequest", + "Must provide did, uri, or blob", + ); + } + + return { + encoding: "application/json", + body: { subject, takedown }, + }; + }, + }); +} diff --git a/services/appview/api/com/atproto/admin/updateSubjectStatus.ts b/services/appview/api/com/atproto/admin/updateSubjectStatus.ts new file mode 100644 index 0000000..d845f03 --- /dev/null +++ b/services/appview/api/com/atproto/admin/updateSubjectStatus.ts @@ -0,0 +1,119 @@ +import { HTTPException } from "hono/http-exception"; +import { AppContext } from "../../../../main.ts"; +import { Server } from "../../../../lexicon/index.ts"; +import type * as ComAtprotoAdminDefs from "../../../../lexicon/types/com/atproto/admin/defs.ts"; +import type * as ComAtprotoRepoStrongRef from "../../../../lexicon/types/com/atproto/repo/strongRef.ts"; +import { AuthRequiredError } from "@atproto/xrpc-server"; + +export default function (server: Server, ctx: AppContext) { + server.com.atproto.admin.updateSubjectStatus({ + auth: ctx.authVerifier.optionalStandardOrRole, + handler: async ({ input, auth }) => { + const { subject, takedown } = input.body; + if (!takedown || typeof takedown.applied !== "boolean") { + throw new HTTPException(400, { message: "Invalid takedown status" }); + } + + const { canPerformTakedown } = ctx.authVerifier.parseCreds(auth); + if (!canPerformTakedown) { + throw new AuthRequiredError("Requires admin privileges"); + } + + try { + if (subject.$type === "com.atproto.admin.defs#repoRef") { + const repoRef = subject as ComAtprotoAdminDefs.RepoRef; + if (!repoRef.did) { + throw new HTTPException(400, { + message: "DID is required for repo takedowns", + }); + } + + if (takedown.applied) { + await ctx.takedownService.takedownRepo({ + did: repoRef.did, + reason: "Moderation action", + adminDid: auth.credentials.type === "standard" + ? auth.credentials.iss + : "admin", + ref: takedown.ref, + }); + await ctx.takedownService.updateRepoTakedownApplied( + repoRef.did, + takedown.applied, + ); + } else { + await ctx.takedownService.removeRepoTakedown(repoRef.did); + } + } else if (subject.$type === "com.atproto.admin.defs#recordRef") { + const recordRef = subject as ComAtprotoRepoStrongRef.Main; + if (!recordRef.uri || !recordRef.cid) { + throw new HTTPException(400, { + message: "URI and CID are required for record takedowns", + }); + } + + if (takedown.applied) { + await ctx.takedownService.takedownContent({ + targetUri: recordRef.uri, + targetCid: recordRef.cid, + reason: "Moderation action", + adminDid: auth.credentials.type === "standard" + ? auth.credentials.iss + : "admin", + }); + await ctx.takedownService.updateTakedownApplied( + recordRef.uri, + takedown.applied, + ); + } else { + await ctx.takedownService.removeTakedown(recordRef.uri); + } + } else if (subject.$type === "com.atproto.admin.defs#repoBlobRef") { + const repoBlobRef = subject as ComAtprotoAdminDefs.RepoBlobRef; + if (!repoBlobRef.did || !repoBlobRef.cid) { + throw new HTTPException(400, { + message: "DID and CID are required for blob takedowns", + }); + } + + if (takedown.applied) { + await ctx.takedownService.takedownBlob({ + did: repoBlobRef.did, + cid: repoBlobRef.cid, + reason: "Moderation action", + adminDid: auth.credentials.type === "standard" + ? auth.credentials.iss + : "admin", + ref: takedown.ref, + }); + await ctx.takedownService.updateBlobTakedownApplied( + repoBlobRef.did, + repoBlobRef.cid, + takedown.applied, + ); + } else { + await ctx.takedownService.removeBlobTakedown( + repoBlobRef.did, + repoBlobRef.cid, + ); + } + } else { + throw new HTTPException(400, { + message: `Unsupported subject type: ${subject.$type}`, + }); + } + + return { + encoding: "application/json", + body: { + subject, + takedown: takedown.applied ? takedown : undefined, + }, + }; + } catch (err) { + if (err instanceof HTTPException) throw err; + throw new HTTPException(500, { message: "Internal server error" }); + } + }, + }); +} diff --git a/services/appview/api/com/atproto/identity/resolveHandle.ts b/services/appview/api/com/atproto/identity/resolveHandle.ts new file mode 100644 index 0000000..dbd4f82 --- /dev/null +++ b/services/appview/api/com/atproto/identity/resolveHandle.ts @@ -0,0 +1,25 @@ +import * as ident from "@atproto/syntax"; +import { InvalidRequestError } from "@atproto/xrpc-server"; +import { AppContext } from "../../../../main.ts"; +import { Hono } from "hono"; + +export const createResolveHandleRouter = (ctx: AppContext) => { + const router = new Hono(); + + router.get("/xrpc/com.atproto.identity.resolveHandle", async (c) => { + if (!c.req.query("handle")) { + throw new InvalidRequestError("Missing handle"); + } + + const handle = ident.normalizeHandle(c.req.query("handle")!); + + const actor = await ctx.db.models.Actor.findOne({ handle }); + if (!actor) { + throw new InvalidRequestError("Unable to resolve handle"); + } + + return c.json({ did: actor.did }); + }); + + return router; +}; diff --git a/services/appview/src/api/com/atproto/repo/getRecord.ts b/services/appview/api/com/atproto/repo/getRecord.ts similarity index 56% rename from services/appview/src/api/com/atproto/repo/getRecord.ts rename to services/appview/api/com/atproto/repo/getRecord.ts index ef8cfd4..7225cd7 100644 --- a/services/appview/src/api/com/atproto/repo/getRecord.ts +++ b/services/appview/api/com/atproto/repo/getRecord.ts @@ -1,68 +1,75 @@ -import { AtUri } from '@atproto/syntax' -import { InvalidRequestError } from '@atproto/xrpc-server' -import { Hono } from 'hono' +import { AtUri } from "@atproto/syntax"; +import { InvalidRequestError } from "@atproto/xrpc-server"; +import { Hono } from "hono"; -import { optionalAuthMiddleware } from '../../../../auth/middleware.js' -import { AppContext } from '../../../../index.js' -import { OutputSchema } from '../../../../lexicon/types/com/atproto/repo/getRecord.js' +import { optionalAuthMiddleware } from "../../../../services/auth/middleware.ts"; +import { AppContext, AppEnv } from "../../../../main.ts"; +import { OutputSchema } from "../../../../lexicon/types/com/atproto/repo/getRecord.ts"; + +interface TakedownInfo { + reason: string; + takenDownBy: string; + takenDownAt: string; + warning: string; +} export const createGetRecordRouter = (ctx: AppContext) => { - const router = new Hono() + const router = new Hono(); router.get( - '/xrpc/com.atproto.repo.getRecord', + "/xrpc/com.atproto.repo.getRecord", optionalAuthMiddleware, async (c) => { - const { repo, collection, rkey, cid } = c.req.query() - const viewerDid = c.get('did') as string | undefined - const isAdmin = c.get('isAdmin') as boolean | undefined - + const { repo, collection, rkey, cid } = c.req.query(); + const isAdmin = c.get("isAdmin") as boolean | undefined; + if (!repo || !collection || !rkey) { - return c.json({ error: 'Missing required parameters' }, 400) + return c.json({ error: "Missing required parameters" }, 400); } // Resolve the handle to DID if needed - let did + let did; try { - if (repo.startsWith('did:')) { - did = repo + if (repo.startsWith("did:")) { + did = repo; } else { // Assume it's a handle - const didDoc = await ctx.resolver.resolveHandleToDidDoc(repo) - did = didDoc.did + const didDoc = await ctx.resolver.resolveHandleToDidDoc(repo); + did = didDoc.did; } - } catch (err) { - throw new InvalidRequestError(`Could not find repo: ${repo}`) + } catch { + throw new InvalidRequestError(`Could not find repo: ${repo}`); } if (!did) { - throw new InvalidRequestError(`Could not find repo: ${repo}`) + throw new InvalidRequestError(`Could not find repo: ${repo}`); } // Create the URI - const uri = AtUri.make(did, collection, rkey).toString() - + const uri = AtUri.make(did, collection, rkey).toString(); + // Get the record based on the collection type try { - let record = null - + let record = null; + // Check which collection to query based on the NSID - if (collection.includes('post') || collection.endsWith('post')) { - record = await ctx.db.models.Post.findOne({ uri }).lean() - } else if (collection.includes('repost')) { - record = await ctx.db.models.Repost.findOne({ uri }).lean() - } else if (collection.includes('like')) { - record = await ctx.db.models.Like.findOne({ uri }).lean() - } else if (collection.includes('look')) { - record = await ctx.db.models.Look.findOne({ uri }).lean() - } else if (collection.includes('profile')) { - record = await ctx.db.models.Profile.findOne({ authorDid: did }).lean() - } else if (collection.includes('follow')) { - record = await ctx.db.models.Follow.findOne({ uri }).lean() - } else if (collection.includes('block')) { - record = await ctx.db.models.Block.findOne({ uri }).lean() + if (collection.includes("post") || collection.endsWith("post")) { + record = await ctx.db.models.Post.findOne({ uri }).lean(); + } else if (collection.includes("repost")) { + record = await ctx.db.models.Repost.findOne({ uri }).lean(); + } else if (collection.includes("like")) { + record = await ctx.db.models.Like.findOne({ uri }).lean(); + } else if (collection.includes("look")) { + record = await ctx.db.models.Look.findOne({ uri }).lean(); + } else if (collection.includes("profile")) { + record = await ctx.db.models.Profile.findOne({ authorDid: did }) + .lean(); + } else if (collection.includes("follow")) { + record = await ctx.db.models.Follow.findOne({ uri }).lean(); + } else if (collection.includes("block")) { + record = await ctx.db.models.Block.findOne({ uri }).lean(); } - + if (!record || (cid && record.cid !== cid)) { // For admins, provide more detailed information about what we tried to query if (isAdmin) { @@ -74,47 +81,48 @@ export const createGetRecordRouter = (ctx: AppContext) => { cid, foundRecord: !!record, cidMatch: record ? (cid ? record.cid === cid : true) : false, - }, 'Admin record lookup failed') + }, "Admin record lookup failed"); } - throw new InvalidRequestError(`Could not locate record: ${uri}`) + throw new InvalidRequestError(`Could not locate record: ${uri}`); } // Check if the record is subject to a takedown - const takedown = await ctx.takedownService.getTakedown(uri) - + const takedown = await ctx.takedownService.getTakedown(uri); + // If record is taken down and user is not an admin, deny access if (takedown && !isAdmin) { - throw new InvalidRequestError(`Record is taken down: ${uri}`) + throw new InvalidRequestError(`Record is taken down: ${uri}`); } - + // Format the response according to the output schema - const response: OutputSchema & { takedown?: any } = { + const response: OutputSchema & { takedown?: TakedownInfo } = { uri: uri, cid: record.cid, - value: record - } - + value: record, + }; + // Include takedown info for admins if (isAdmin && takedown) { response.takedown = { reason: takedown.reason, takenDownBy: takedown.takenDownBy, takenDownAt: takedown.takenDownAt, - warning: 'This content has been taken down and is only visible to admins' - } + warning: + "This content has been taken down and is only visible to admins", + }; } - - return c.json(response) + + return c.json(response); } catch (err) { if (err instanceof InvalidRequestError) { - throw err + throw err; } - throw new InvalidRequestError(`Error retrieving record: ${uri}`) + throw new InvalidRequestError(`Error retrieving record: ${uri}`); } }, - ) + ); - return router -} + return router; +}; -export default (ctx: AppContext) => createGetRecordRouter(ctx) \ No newline at end of file +export default (ctx: AppContext) => createGetRecordRouter(ctx); diff --git a/services/appview/src/api/index.ts b/services/appview/api/index.ts similarity index 53% rename from services/appview/src/api/index.ts rename to services/appview/api/index.ts index dc4e5f2..00ef6a6 100644 --- a/services/appview/src/api/index.ts +++ b/services/appview/api/index.ts @@ -1,11 +1,11 @@ -import { Server } from '../lexicon/index.js' -import { AppContext } from "../index.js"; -import getAccountInfos from "./com/atproto/admin/getAccountInfos.js"; -import getSubjectStatus from "./com/atproto/admin/getSubjectStatus.js"; -import updateSubjectStatus from "./com/atproto/admin/updateSubjectStatus.js"; +import { Server } from "../lexicon/index.ts"; +import { AppContext } from "../main.ts"; +import getAccountInfos from "./com/atproto/admin/getAccountInfos.ts"; +import getSubjectStatus from "./com/atproto/admin/getSubjectStatus.ts"; +import updateSubjectStatus from "./com/atproto/admin/updateSubjectStatus.ts"; export default function (server: Server, ctx: AppContext) { - getAccountInfos(server, ctx); - getSubjectStatus(server, ctx); - updateSubjectStatus(server, ctx); + getAccountInfos(server, ctx); + getSubjectStatus(server, ctx); + updateSubjectStatus(server, ctx); } diff --git a/services/appview/api/so/sprk/actor/getPreferences.ts b/services/appview/api/so/sprk/actor/getPreferences.ts new file mode 100644 index 0000000..a4663e4 --- /dev/null +++ b/services/appview/api/so/sprk/actor/getPreferences.ts @@ -0,0 +1,33 @@ +import { Hono } from "hono"; +import { AppContext, AppEnv } from "../../../../main.ts"; +import { authMiddleware } from "../../../../services/auth/middleware.ts"; + +export const createGetPreferencesRouter = (ctx: AppContext) => { + const router = new Hono(); + + router.get( + "/xrpc/so.sprk.actor.getPreferences", + authMiddleware, + async (c) => { + const userDid = c.get("did") as string; + + try { + const userPref = await ctx.db.models.UserPreference.findOne({ + userDid, + }); + + return c.json( + { + followMode: userPref?.followMode || "sprk", + }, + 200, + ); + } catch (error) { + ctx.logger.error({ error, userDid }, "Failed to get preferences"); + return c.json({ error: "Failed to get preferences" }, 500); + } + }, + ); + + return router; +}; diff --git a/services/appview/src/api/so/sprk/actor/getProfile.ts b/services/appview/api/so/sprk/actor/getProfile.ts similarity index 62% rename from services/appview/src/api/so/sprk/actor/getProfile.ts rename to services/appview/api/so/sprk/actor/getProfile.ts index d339543..c2706e8 100644 --- a/services/appview/src/api/so/sprk/actor/getProfile.ts +++ b/services/appview/api/so/sprk/actor/getProfile.ts @@ -1,185 +1,185 @@ -import { ensureValidDid, isValidHandle } from '@atproto/syntax' -import { Hono } from 'hono' +import { ensureValidDid, isValidHandle } from "@atproto/syntax"; +import { Hono } from "hono"; -import { optionalAuthMiddleware } from '../../../../auth/middleware.js' -import { AppContext } from '../../../../index.js' -import type { Label } from '../../../../lexicon/types/com/atproto/label/defs.js' -import type * as ComAtprotoRepoStrongRef from '../../../../lexicon/types/com/atproto/repo/strongRef.js' -import type * as SoSprkActorDefs from '../../../../lexicon/types/so/sprk/actor/defs.js' +import { optionalAuthMiddleware } from "../../../../services/auth/middleware.ts"; +import { AppContext, AppEnv } from "../../../../main.ts"; +import type { Label } from "../../../../lexicon/types/com/atproto/label/defs.ts"; +import type * as ComAtprotoRepoStrongRef from "../../../../lexicon/types/com/atproto/repo/strongRef.ts"; +import type * as SoSprkActorDefs from "../../../../lexicon/types/so/sprk/actor/defs.ts"; export const createGetProfileRouter = (ctx: AppContext) => { - const router = new Hono() + const router = new Hono(); router.get( - '/xrpc/so.sprk.actor.getProfile', + "/xrpc/so.sprk.actor.getProfile", optionalAuthMiddleware, async (c) => { - const actorParam = c.req.query('actor') - const viewerDid = c.get('did') as string | undefined + const actorParam = c.req.query("actor"); + const viewerDid = c.get("did") as string | undefined; if (!actorParam) { - return c.json({ error: 'Actor not provided' }, 400) + return c.json({ error: "Actor not provided" }, 400); } - let actorDidDoc + let actorDidDoc; if (isValidHandle(actorParam)) { - actorDidDoc = await ctx.resolver.resolveHandleToDidDoc(actorParam) + actorDidDoc = await ctx.resolver.resolveHandleToDidDoc(actorParam); } else { try { - ensureValidDid(actorParam) - actorDidDoc = await ctx.resolver.resolveDidToDidDoc(actorParam) - } catch (err) { - return c.json({ error: 'Invalid actor' }, 400) + ensureValidDid(actorParam); + actorDidDoc = await ctx.resolver.resolveDidToDidDoc(actorParam); + } catch { + return c.json({ error: "Invalid actor" }, 400); } } - const actorDid = actorDidDoc.did + const actorDid = actorDidDoc.did; - const now = new Date().toISOString() + const now = new Date().toISOString(); - await ctx.indexingService.indexHandle(actorDid, now) + await ctx.indexingService.indexHandle(actorDid, now); // First check if actor exists and has profile let actorDoc = await ctx.db.models.Actor.findOne({ did: actorDid, - }) + }); - let profile = await ctx.db.models.Profile.findOne({ + const profile = await ctx.db.models.Profile.findOne({ authorDid: actorDid, - }) + }); if (!actorDoc) { try { ctx.logger.info( { did: actorDid }, - 'No profile found, attempting to index', - ) - await ctx.indexingService.indexHandle(actorDid, now, true) + "No profile found, attempting to index", + ); + await ctx.indexingService.indexHandle(actorDid, now, true); // Refetch after indexing actorDoc = await ctx.db.models.Actor.findOne({ did: actorDid, - }) + }); } catch (error) { - ctx.logger.error({ error, did: actorDid }, 'Failed to index handle') + ctx.logger.error({ error, did: actorDid }, "Failed to index handle"); } } if (!actorDoc) { - return c.json({ error: 'Actor not found' }, 404) + return c.json({ error: "Actor not found" }, 404); } if (!profile) { - return c.json({ error: 'Profile not found' }, 404) + return c.json({ error: "Profile not found" }, 404); } // Use actor's handle if available, otherwise resolve from DID - const handle = - actorDoc.handle || (await ctx.resolver.resolveDidToHandle(actorDid)) + const handle = actorDoc.handle || + (await ctx.resolver.resolveDidToHandle(actorDid)); // Get actor's preference for follow mode (used for both viewer state and counting) const actorPref = await ctx.db.models.UserPreference.findOne({ userDid: actorDid, - }) - const actorFollowMode = actorPref?.followMode || 'sprk' + }); + const actorFollowMode = actorPref?.followMode || "sprk"; // Build viewer state if a user is authenticated - const viewer: SoSprkActorDefs.ViewerState = {} + const viewer: SoSprkActorDefs.ViewerState = {}; if (viewerDid) { // Determine follow mode from viewer's preference for checking if viewer follows profile const viewerPref = await ctx.db.models.UserPreference.findOne({ userDid: viewerDid, - }) - const viewerFollowMode = viewerPref?.followMode || 'sprk' + }); + const viewerFollowMode = viewerPref?.followMode || "sprk"; // Check if viewer follows this profile (use viewer's follow mode) const follow = await ctx.db.models.Follow.findOne({ subject: actorDid, authorDid: viewerDid, type: viewerFollowMode, - }) - if (follow) viewer.following = follow.uri + }); + if (follow) viewer.following = follow.uri; // Check if this profile follows the viewer (use profile owner's follow mode) const followedBy = await ctx.db.models.Follow.findOne({ subject: viewerDid, authorDid: actorDid, type: actorFollowMode, - }) - if (followedBy) viewer.followedBy = followedBy.uri + }); + if (followedBy) viewer.followedBy = followedBy.uri; // Check block relationships const block = await ctx.db.models.Block.findOne({ subject: actorDid, authorDid: viewerDid, - }) - if (block) viewer.blocking = block.uri + }); + if (block) viewer.blocking = block.uri; const blockedBy = await ctx.db.models.Block.findOne({ subject: viewerDid, authorDid: actorDid, - }) - if (blockedBy) viewer.blockedBy = true + }); + if (blockedBy) viewer.blockedBy = true; } // Check for associated services - const associated: SoSprkActorDefs.ProfileAssociated = {} + const associated: SoSprkActorDefs.ProfileAssociated = {}; // Check for feed generators - let feedgensCount = 0 + let feedgensCount = 0; try { if (ctx.db.models.Generator) { feedgensCount = await ctx.db.models.Generator.countDocuments({ authorDid: actorDid, - }) + }); } - } catch (error) { + } catch { // Ignore if model doesn't exist } if (feedgensCount > 0) { - associated.feedgens = feedgensCount + associated.feedgens = feedgensCount; } // Get avatar and banner URLs const avatar = profile.avatar ? `https://media.sprk.so/avatar/tiny/${actorDid}/${profile.avatar.ref.$link}/webp` - : undefined + : undefined; const banner = profile.banner ? `https://media.sprk.so/img/tiny/${actorDid}/${profile.banner.ref.$link}/webp` - : undefined + : undefined; // Convert labels to the correct type if it exists - let labels: Label[] | undefined = undefined + let labels: Label[] | undefined = undefined; if (profile.labels) { labels = Array.isArray(profile.labels) ? (profile.labels as Label[]) - : undefined + : undefined; } // Convert pinnedPost to the correct type if it exists - let pinnedPost: ComAtprotoRepoStrongRef.Main | undefined = undefined + let pinnedPost: ComAtprotoRepoStrongRef.Main | undefined = undefined; if (profile.pinnedPost) { - pinnedPost = - profile.pinnedPost as unknown as ComAtprotoRepoStrongRef.Main + pinnedPost = profile + .pinnedPost as unknown as ComAtprotoRepoStrongRef.Main; } // Count unique followers across both Sprk and Bsky follow types const followersCount = await ctx.db.models.Follow.aggregate([ { $match: { subject: actorDid } }, - { $group: { _id: '$authorDid' } }, - { $count: 'total' }, - ]).then((result) => result[0]?.total || 0) + { $group: { _id: "$authorDid" } }, + { $count: "total" }, + ]).then((result) => result[0]?.total || 0); // Count follows based on actor's follow mode preference const followsCount = await ctx.db.models.Follow.countDocuments({ authorDid: actorDid, type: actorFollowMode, - }) + }); const postsCount = await ctx.db.models.Post.countDocuments({ authorDid: actorDid, - }) + }); // Build the ProfileViewDetailed response const profileView: SoSprkActorDefs.ProfileViewDetailed = { @@ -198,11 +198,11 @@ export const createGetProfileRouter = (ctx: AppContext) => { viewer: Object.keys(viewer).length > 0 ? viewer : undefined, labels, pinnedPost, - } + }; - return c.json(profileView) + return c.json(profileView); }, - ) + ); - return router -} + return router; +}; diff --git a/services/appview/api/so/sprk/actor/putPreferences.ts b/services/appview/api/so/sprk/actor/putPreferences.ts new file mode 100644 index 0000000..f7dcdb2 --- /dev/null +++ b/services/appview/api/so/sprk/actor/putPreferences.ts @@ -0,0 +1,61 @@ +import { Hono } from "hono"; +import { AppContext, AppEnv } from "../../../../main.ts"; +import { authMiddleware } from "../../../../services/auth/middleware.ts"; +import * as SoSprkActorPutPreferences from "../../../../lexicon/types/so/sprk/actor/putPreferences.ts"; + +export const createPutPreferencesRouter = (ctx: AppContext) => { + const router = new Hono(); + + router.post( + "/xrpc/so.sprk.actor.putPreferences", + authMiddleware, + async (c) => { + const userDid = c.get("did") as string; + const body = await c.req.json() as SoSprkActorPutPreferences.InputSchema; + + if (body.followMode && !["bsky", "sprk"].includes(body.followMode)) { + return c.json( + { error: 'Invalid followMode parameter. Must be "bsky" or "sprk"' }, + 400, + ); + } + + try { + const now = new Date().toISOString(); + let userPref = await ctx.db.models.UserPreference.findOne({ userDid }); + const oldMode = userPref?.followMode; + + if (!userPref) { + userPref = await ctx.db.models.UserPreference.create({ + userDid, + createdAt: now, + updatedAt: now, + followMode: body.followMode || "sprk", // Default if not provided + }); + } else { + if (body.followMode) { + userPref.followMode = body.followMode; + } + userPref.updatedAt = now; + await userPref.save(); + } + + // Queue indexing of Bsky follows if switched to bsky mode + const indexingService = c.env.indexingService; + if (body.followMode === "bsky" && oldMode !== "bsky") { + indexingService.indexBSkyFollows(userDid).catch((error) => + ctx.logger.error({ error, userDid }, "Failed to index bsky follows") + ); + } + + // Respond with all current preferences, including the updated followMode + return c.json({ followMode: userPref.followMode }, 200); + } catch (error) { + ctx.logger.error({ error, userDid }, "Failed to put preferences"); + return c.json({ error: "Failed to put preferences" }, 500); + } + }, + ); + + return router; +}; diff --git a/services/appview/src/api/so/sprk/actor/searchActors.ts b/services/appview/api/so/sprk/actor/searchActors.ts similarity index 53% rename from services/appview/src/api/so/sprk/actor/searchActors.ts rename to services/appview/api/so/sprk/actor/searchActors.ts index 624cc66..eb0f3a5 100644 --- a/services/appview/src/api/so/sprk/actor/searchActors.ts +++ b/services/appview/api/so/sprk/actor/searchActors.ts @@ -1,96 +1,98 @@ -import { Hono } from 'hono' -import { optionalAuthMiddleware } from '../../../../auth/middleware.js' -import { AppContext } from '../../../../index.js' -import type { Label } from '../../../../lexicon/types/com/atproto/label/defs.js' -import type * as SoSprkActorDefs from '../../../../lexicon/types/so/sprk/actor/defs.js' -import type * as SoSprkActorSearch from '../../../../lexicon/types/so/sprk/actor/searchActors.js' +import { Hono } from "hono"; +import { optionalAuthMiddleware } from "../../../../services/auth/middleware.ts"; +import { AppContext, AppEnv } from "../../../../main.ts"; +import type { Label } from "../../../../lexicon/types/com/atproto/label/defs.ts"; +import type * as SoSprkActorDefs from "../../../../lexicon/types/so/sprk/actor/defs.ts"; +import type * as SoSprkActorSearch from "../../../../lexicon/types/so/sprk/actor/searchActors.ts"; // Helper to escape user input for safe RegExp usage function escapeRegExp(str: string): string { - return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } export const createSearchActorRouter = (ctx: AppContext) => { - const router = new Hono() + const router = new Hono(); router.get( - '/xrpc/so.sprk.actor.searchActors', + "/xrpc/so.sprk.actor.searchActors", optionalAuthMiddleware, async (c) => { - const q = c.req.query('q')?.trim() + const q = c.req.query("q")?.trim(); if (!q) { - return c.json({ error: 'Search query (q) is required' }, 400) + return c.json({ error: "Search query (q) is required" }, 400); } - let limit = parseInt(c.req.query('limit') ?? '25') - if (isNaN(limit)) limit = 25 + let limit = parseInt(c.req.query("limit") ?? "25"); + if (isNaN(limit)) limit = 25; if (limit < 1 || limit > 100) { - return c.json({ error: 'Limit must be between 1 and 100' }, 400) + return c.json({ error: "Limit must be between 1 and 100" }, 400); } - let skip = 0 - const cursorParam = c.req.query('cursor') + let skip = 0; + const cursorParam = c.req.query("cursor"); if (cursorParam) { - skip = parseInt(cursorParam) + skip = parseInt(cursorParam); if (isNaN(skip) || skip < 0) { - return c.json({ error: 'Invalid cursor' }, 400) + return c.json({ error: "Invalid cursor" }, 400); } } - const filter: any = {} - const sort: any = { createdAt: -1 } + const filter: Record = {}; + const sort: { createdAt: -1 } = { createdAt: -1 }; - const escaped = escapeRegExp(q) - const regex = new RegExp(escaped, 'i') + const escaped = escapeRegExp(q); + const regex = new RegExp(escaped, "i"); filter.$or = [ { displayName: regex }, { description: regex }, { handle: regex }, - ] + ]; const profiles = await ctx.db.models.Profile.find(filter) .sort(sort) .skip(skip) .limit(limit) - .lean() + .lean(); // For handle search, exclude DIDs already found - const foundDids = profiles.map((p) => p.authorDid) - const handleFilter = { ...filter, did: { $nin: foundDids } } + const foundDids = profiles.map((p: { authorDid: string }) => p.authorDid); + const handleFilter = { ...filter, did: { $nin: foundDids } }; const handles = await ctx.db.models.Actor.find(handleFilter) .sort(sort) .skip(skip) .limit(limit) - .lean() + .lean(); const handleProfiles = await ctx.db.models.Profile.find({ - authorDid: { $in: handles.map((h) => h.did) }, - }).lean() + authorDid: { $in: handles.map((h: { did: string }) => h.did) }, + }).lean(); - const fullProfiles = [...profiles, ...handleProfiles] + const fullProfiles = [...profiles, ...handleProfiles]; - const viewerDid = c.get('did') as string | undefined + const viewerDid = c.get("did") as string | undefined; const actors: SoSprkActorDefs.ProfileView[] = ( await Promise.all( fullProfiles.map(async (p) => { const avatar = p.avatar - ? `https://media.sprk.so/avatar/tiny/${p.authorDid}/${(p.avatar as any).ref.$link}/webp` - : undefined + ? `https://media.sprk.so/avatar/tiny/${p.authorDid}/${ + (p.avatar as { ref: { $link: string } }).ref.$link + }/webp` + : undefined; const labels = Array.isArray(p.labels) ? (p.labels as Label[]) - : undefined - const now = new Date().toISOString() - await ctx.indexingService.indexHandle(p.authorDid, now) + : undefined; + const now = new Date().toISOString(); + await ctx.indexingService.indexHandle(p.authorDid, now); const actor = await ctx.db.models.Actor.findOne({ did: p.authorDid, - }) + }); if (!actor || !actor.handle) { - return undefined + return undefined; } - let viewer: SoSprkActorDefs.ViewerState | undefined = undefined + let viewer: SoSprkActorDefs.ViewerState | undefined = undefined; if (viewerDid) { const [follow, followedBy, block, blockedBy] = await Promise.all([ ctx.db.models.Follow.findOne({ @@ -109,18 +111,18 @@ export const createSearchActorRouter = (ctx: AppContext) => { subject: viewerDid, authorDid: p.authorDid, }), - ]) - console.log(follow, followedBy, block, blockedBy) - viewer = {} - if (follow) viewer.following = follow.uri - if (followedBy) viewer.followedBy = followedBy.uri - if (block) viewer.blocking = block.uri - if (blockedBy) viewer.blockedBy = true - if (Object.keys(viewer).length === 0) viewer = undefined + ]); + console.log(follow, followedBy, block, blockedBy); + viewer = {}; + if (follow) viewer.following = follow.uri; + if (followedBy) viewer.followedBy = followedBy.uri; + if (block) viewer.blocking = block.uri; + if (blockedBy) viewer.blockedBy = true; + if (Object.keys(viewer).length === 0) viewer = undefined; } return { - $type: 'so.sprk.actor.defs#profileView', + $type: "so.sprk.actor.defs#profileView", did: p.authorDid, handle: actor.handle, displayName: p.displayName, @@ -130,23 +132,24 @@ export const createSearchActorRouter = (ctx: AppContext) => { createdAt: p.createdAt, labels, viewer, - } as SoSprkActorDefs.ProfileView + } as SoSprkActorDefs.ProfileView; }), ) ).filter( (actor): actor is SoSprkActorDefs.ProfileView => actor !== undefined, - ) + ); - const nextCursor = - profiles.length === limit ? String(skip + limit) : undefined - const result: SoSprkActorSearch.OutputSchema = { actors } + const nextCursor = profiles.length === limit + ? String(skip + limit) + : undefined; + const result: SoSprkActorSearch.OutputSchema = { actors }; if (nextCursor) { - result.cursor = nextCursor + result.cursor = nextCursor; } - return c.json(result) + return c.json(result); }, - ) + ); - return router -} + return router; +}; diff --git a/services/appview/api/so/sprk/feed/getAuthorFeed.ts b/services/appview/api/so/sprk/feed/getAuthorFeed.ts new file mode 100644 index 0000000..59b2475 --- /dev/null +++ b/services/appview/api/so/sprk/feed/getAuthorFeed.ts @@ -0,0 +1,188 @@ +import { Hono } from "hono"; +import { HTTPException } from "hono/http-exception"; +import { optionalAuthMiddleware } from "../../../../services/auth/middleware.ts"; +import { AppContext, AppEnv } from "../../../../main.ts"; +import { transformPostToPostView } from "../../../../utils/post-transformer.ts"; +import { decodeBase64, encodeBase64 } from "jsr:@std/encoding"; + +export const createGetAuthorFeedRouter = (ctx: AppContext) => { + const router = new Hono(); + + router.get( + "/xrpc/so.sprk.feed.getAuthorFeed", + optionalAuthMiddleware, + async (c) => { + // Get query parameters + const actor = c.req.query("actor"); + const limit = parseInt(c.req.query("limit") || "50", 10); + const cursor = c.req.query("cursor"); + const filter = c.req.query("filter") || "posts_with_replies"; + const includePins = c.req.query("includePins") === "true"; + const viewerDid = c.var.did as string | undefined; + + // Validate required parameters + if (!actor) { + throw new HTTPException(400, { message: "Actor is required" }); + } + + // Validate limit + if (isNaN(limit) || limit < 1 || limit > 100) { + throw new HTTPException(400, { + message: "Invalid limit: must be between 1 and 100", + }); + } + + try { + // Resolve DID if handle is provided + let actorDid = actor; + if (!actorDid.startsWith("did:")) { + try { + const didDoc = await ctx.resolver.resolveHandleToDidDoc(actor); + actorDid = didDoc.did; + } catch { + throw new HTTPException(400, { + message: "Invalid actor: could not resolve handle", + }); + } + } + + // Check if user is blocked or blocking the actor + if (viewerDid) { + const userIsBlocked = await ctx.db.models.Block.findOne({ + authorDid: actorDid, + subject: viewerDid, + }); + + if (userIsBlocked) { + throw new HTTPException(403, { message: "BlockedByActor" }); + } + + const userIsBlocking = await ctx.db.models.Block.findOne({ + authorDid: viewerDid, + subject: actorDid, + }); + + if (userIsBlocking) { + throw new HTTPException(403, { message: "BlockedActor" }); + } + } + + // Build query based on filter + type MongoQuery = { + authorDid: string; + reply: null; + $or?: Array<{ [key: string]: unknown }>; + [key: string]: unknown; + }; + + const query: MongoQuery = { authorDid: actorDid, reply: null }; + + if (filter === "posts_with_media") { + query.$or = [ + { "embed.$type": "so.sprk.embed.images" }, + { "embed.$type": "so.sprk.embed.video" }, + ]; + } else if (filter === "posts_with_video") { + query["embed.$type"] = "so.sprk.embed.video"; + } + + // Parse cursor if provided + let createdAtCursor; + let idCursor; + + if (cursor) { + try { + const decodedCursor = new TextDecoder().decode( + decodeBase64(cursor), + ); + const [timestamp, id] = decodedCursor.split("::"); + createdAtCursor = timestamp; + idCursor = id; + } catch { + throw new HTTPException(400, { message: "Invalid cursor format" }); + } + } + + // Add cursor-based pagination + if (createdAtCursor && idCursor) { + query.$or = [ + { createdAt: { $lt: createdAtCursor } }, + { createdAt: createdAtCursor, _id: { $lt: idCursor } }, + ]; + } + + // Get posts from database + const posts = await ctx.db.models.Post.find(query) + .sort({ createdAt: -1, _id: -1 }) + .limit(limit + 1) // Get one extra for cursor + .lean(); + + // Check if we have more results (for cursor) + const hasMore = posts.length > limit; + if (hasMore) { + posts.pop(); // Remove the extra item + } + + // Include pinned posts if requested + const pinnedPosts = []; + if (includePins) { + // Get profile to find pinned posts + const profile = await ctx.db.models.Profile.findOne({ + authorDid: actorDid, + }).lean(); + + if (profile?.pinnedPost) { + const pinnedPostUri = profile.pinnedPost.uri; + const pinnedPost = await ctx.db.models.Post.findOne({ + uri: pinnedPostUri, + }).lean(); + + if (pinnedPost) { + pinnedPosts.push(pinnedPost); + } + } + } + + // Transform posts to feed view posts + const feedViewPosts = await Promise.all( + [...pinnedPosts, ...posts].map(async (post) => { + const postView = await transformPostToPostView( + post, + ctx.db, + viewerDid, + ); + + return { + post: postView, + }; + }), + ); + + // Generate next cursor if there are more results + let nextCursor; + if (hasMore && posts.length > 0) { + const lastPost = posts[posts.length - 1]; + nextCursor = encodeBase64( + new TextEncoder().encode(`${lastPost.createdAt}::${lastPost._id}`), + ); + } + + return c.json({ + cursor: nextCursor, + feed: feedViewPosts, + }); + } catch (error) { + if (error instanceof HTTPException) { + throw error; + } + + console.error("Error fetching author feed:", error); + throw new HTTPException(500, { + message: "Failed to fetch author feed", + }); + } + }, + ); + + return router; +}; diff --git a/services/appview/api/so/sprk/feed/getPostThread.ts b/services/appview/api/so/sprk/feed/getPostThread.ts new file mode 100644 index 0000000..6d68434 --- /dev/null +++ b/services/appview/api/so/sprk/feed/getPostThread.ts @@ -0,0 +1,187 @@ +import { Hono } from "hono"; +import { OutputSchema as GetPostThreadView } from "../../../../lexicon/types/so/sprk/feed/getPostThread.ts"; +import type * as SoSprkFeedDefs from "../../../../lexicon/types/so/sprk/feed/defs.ts"; +import { AppContext, AppEnv } from "../../../../main.ts"; +import { transformPostToPostView } from "../../../../utils/post-transformer.ts"; +import { optionalAuthMiddleware } from "../../../../services/auth/middleware.ts"; + +export const createGetPostThreadRouter = (ctx: AppContext) => { + const router = new Hono(); + + router.get( + "/xrpc/so.sprk.feed.getPostThread", + optionalAuthMiddleware, + async (c) => { + const uri = c.req.query("uri"); + const depth = parseInt(c.req.query("depth") || "6", 10); + const parentHeight = parseInt(c.req.query("parentHeight") || "80", 10); + const userDid = c.get("did") as string | undefined; + + if (!uri) { + return c.json({ error: "URI is required" }, 400); + } + + try { + // Get the requested post + const mainPost = await ctx.db.models.Post.findOne({ uri }).lean(); + + if (!mainPost) { + return c.json({ + thread: { + $type: "so.sprk.feed.defs#notFoundPost", + uri, + notFound: true, + }, + } as GetPostThreadView, 404); + } + + // Convert the main post to a PostView + const mainPostView = await transformPostToPostView( + mainPost, + ctx.db, + userDid, + ); + + // Get parent posts if this is a reply + const parentPosts: SoSprkFeedDefs.PostView[] = []; + + if (mainPost.reply) { + // Navigate up to the root collecting parent posts + let currentParentUri = mainPost.reply.parent.uri; + let parentsCollected = 0; + + while (currentParentUri && parentsCollected < parentHeight) { + const parentPost = await ctx.db.models.Post.findOne({ + uri: currentParentUri, + }).lean(); + + if (!parentPost) { + break; + } + + const parentPostView = await transformPostToPostView( + parentPost, + ctx.db, + userDid, + ); + parentPosts.unshift(parentPostView); // Add at the beginning so root is first + + // If we reached the root, stop + if (!parentPost.reply) { + break; + } + + // Move to the next parent + currentParentUri = parentPost.reply.parent.uri; + parentsCollected++; + } + } + + // Get replies to the main post (direct children) + const replies = await ctx.db.models.Post.find({ + "reply.parent.uri": mainPost.uri, + }).sort({ createdAt: 1 }).lean(); + + // Convert replies to thread views recursively + const replyThreads = await Promise.all( + replies.map(async (reply: { uri: string }) => { + return await buildThreadView(reply, ctx, userDid, depth - 1); + }), + ); + + // Check for user specific thread context + const threadContext: SoSprkFeedDefs.ThreadContext = {}; + + // Build the main thread view + const thread = { + $type: "so.sprk.feed.defs#threadViewPost", + post: mainPostView, + replies: replyThreads, + threadContext, + } as SoSprkFeedDefs.ThreadViewPost; + + // Add parent if it exists + if (parentPosts.length > 0) { + // Create a nested parent structure + let currentParent: { + $type: string; + post: SoSprkFeedDefs.PostView; + parent?: unknown; + replies: SoSprkFeedDefs.ThreadViewPost[]; + threadContext: SoSprkFeedDefs.ThreadContext; + } | undefined = undefined; + + // Build parent thread structure from oldest to newest + for (const parentPost of parentPosts) { + currentParent = { + $type: "so.sprk.feed.defs#threadViewPost", + post: parentPost, + parent: currentParent, + replies: [], + threadContext: {}, + }; + } + + // Set the direct parent of the main post + thread.parent = currentParent; + } + + return c.json({ thread } as GetPostThreadView); + } catch (error) { + console.error("Error fetching post thread:", error); + return c.json({ error: "Failed to get post thread" }, 500); + } + }, + ); + + return router; +}; + +// Recursive function to build a thread view for a post and its replies +async function buildThreadView( + post: { uri: string; reply?: { parent: { uri: string } } }, + ctx: AppContext, + userDid?: string, + depth = 0, +): Promise { + // Get the full post document + const fullPost = await ctx.db.models.Post.findOne({ uri: post.uri }).lean(); + if (!fullPost) { + throw new Error(`Post not found: ${post.uri}`); + } + + // Convert the post to a post view + const postView = await transformPostToPostView(fullPost, ctx.db, userDid); + + // If we've reached the maximum depth, don't fetch replies + if (depth <= 0) { + return { + $type: "so.sprk.feed.defs#threadViewPost", + post: postView, + replies: [], + threadContext: {}, + } as SoSprkFeedDefs.ThreadViewPost; + } + + // Get replies to this post + const replies = await ctx.db.models.Post.find({ + "reply.parent.uri": post.uri, + }).sort({ createdAt: 1 }).lean(); + + // Convert replies to thread views recursively + const replyThreads = await Promise.all( + replies.map(async (reply: { uri: string }) => { + return await buildThreadView(reply, ctx, userDid, depth - 1); + }), + ); + + // Check for user specific thread context + const threadContext: SoSprkFeedDefs.ThreadContext = {}; + + return { + $type: "so.sprk.feed.defs#threadViewPost", + post: postView, + replies: replyThreads, + threadContext, + } as SoSprkFeedDefs.ThreadViewPost; +} diff --git a/services/appview/api/so/sprk/feed/getPosts.ts b/services/appview/api/so/sprk/feed/getPosts.ts new file mode 100644 index 0000000..6dfc9df --- /dev/null +++ b/services/appview/api/so/sprk/feed/getPosts.ts @@ -0,0 +1,56 @@ +import { Hono } from "hono"; + +import { OutputSchema as GetPostsView } from "../../../../lexicon/types/so/sprk/feed/getPosts.ts"; +import { AppContext, AppEnv } from "../../../../main.ts"; +import { transformPostToPostView } from "../../../../utils/post-transformer.ts"; +import { Database } from "../../../../services/data-plane/server/index.ts"; +import type * as SoSprkFeedDefs from "../../../../lexicon/types/so/sprk/feed/defs.ts"; +import { optionalAuthMiddleware } from "../../../../services/auth/middleware.ts"; + +// Function to fetch posts by URIs +async function getPosts( + uris: string | string[], + db: Database, + userDid?: string, +): Promise { + if (!uris) { + return []; + } + + const uriArray = Array.isArray(uris) ? uris : [uris]; + + if (uriArray.length === 0) { + return []; + } + + const dbPosts = await db.models.Post.find({ uri: { $in: uriArray } }).lean(); + + // Transform each post to PostView format + const postViews = await Promise.all( + dbPosts.map((post) => transformPostToPostView(post, db, userDid)), + ); + + return postViews; +} + +export const createGetPostsRouter = (ctx: AppContext) => { + const router = new Hono(); + + router.get( + "/xrpc/so.sprk.feed.getPosts", + optionalAuthMiddleware, + async (c) => { + const uris = c.req.queries("uris"); + const userDid = c.get("did") as string | undefined; + + if (!uris || uris.length === 0) { + return c.json({ posts: [] } as GetPostsView); + } + + const posts = await getPosts(uris, ctx.db, userDid); + + return c.json({ posts } as GetPostsView); + }, + ); + return router; +}; diff --git a/services/appview/api/so/sprk/graph/getFollowers.ts b/services/appview/api/so/sprk/graph/getFollowers.ts new file mode 100644 index 0000000..223cfa4 --- /dev/null +++ b/services/appview/api/so/sprk/graph/getFollowers.ts @@ -0,0 +1,126 @@ +import { Hono } from "hono"; + +import { optionalAuthMiddleware } from "../../../../services/auth/middleware.ts"; +import { AppContext } from "../../../../main.ts"; +import type * as SoSprkActorDefs from "../../../../lexicon/types/so/sprk/actor/defs.ts"; + +export const createGetFollowersRouter = (ctx: AppContext) => { + const router = new Hono(); + + router.get( + "/xrpc/so.sprk.graph.getFollowers", + optionalAuthMiddleware, + async (c) => { + const actor = c.req.query("actor"); + const limit = parseInt(c.req.query("limit") ?? "50"); + const cursor = c.req.query("cursor"); + + if (!actor) { + return c.json({ error: "Actor is required" }, 400); + } + + // Validate limit + if (limit < 1 || limit > 100) { + return c.json({ error: "Limit must be between 1 and 100" }, 400); + } + + // Build query + const query: { subject: string; _id?: { $gt: string } } = { + subject: actor, + }; + if (cursor) { + query._id = { $gt: cursor }; + } + + // Get followers with pagination + const followers = await ctx.db.models.Follow.find(query) + .sort({ _id: 1 }) + .limit(limit) + .lean(); + + // Get profile views for each follower + const profileViews = await Promise.all( + followers.map(async (follow) => { + const profile = await ctx.db.models.Profile.findOne({ + authorDid: follow.authorDid, + }); + + // Basic profile view with just DID and handle + const basicProfileView: SoSprkActorDefs.ProfileView = { + $type: "so.sprk.actor.defs#profileView", + did: follow.authorDid, + handle: follow.authorHandle, + viewer: { + $type: "so.sprk.actor.defs#viewerState", + following: follow.uri, + }, + }; + + // If we found a profile, add the additional fields + if (profile) { + return { + ...basicProfileView, + displayName: profile.displayName, + description: profile.description, + avatar: profile.avatar?.ref?.$link, + indexedAt: profile.indexedAt, + createdAt: profile.createdAt, + }; + } + + return basicProfileView; + }), + ); + + // Get next cursor + const nextCursor = followers.length === limit + ? followers[followers.length - 1]._id + : undefined; + console.log("nextCursor", nextCursor); + + // Get subject profile if it exists + const subjectProfile = await ctx.db.models.Profile.findOne({ + authorDid: actor, + }); + + // Basic subject profile view with just DID and handle + let handle = null; + try { + if (actor) { + const didData = await ctx.resolver.resolveDidToDidDoc(actor); + handle = didData.handle; + } + } catch (error) { + ctx.logger.warn( + { did: actor, error: (error as Error).message }, + "Failed to resolve DID to handle", + ); + } + const subjectProfileView: SoSprkActorDefs.ProfileView = { + $type: "so.sprk.actor.defs#profileView", + did: actor, + handle: handle ?? "unknown", + }; + + // If we found the subject profile, add the additional fields + if (subjectProfile) { + Object.assign(subjectProfileView, { + handle: subjectProfile.authorHandle, + displayName: subjectProfile.displayName, + description: subjectProfile.description, + avatar: subjectProfile.avatar?.ref?.$link, + indexedAt: subjectProfile.indexedAt, + createdAt: subjectProfile.createdAt, + }); + } + + return c.json({ + subject: subjectProfileView, + followers: profileViews, + cursor: nextCursor, + }); + }, + ); + + return router; +}; diff --git a/services/appview/api/so/sprk/graph/getFollows.ts b/services/appview/api/so/sprk/graph/getFollows.ts new file mode 100644 index 0000000..fe788d5 --- /dev/null +++ b/services/appview/api/so/sprk/graph/getFollows.ts @@ -0,0 +1,169 @@ +import { Hono } from "hono"; +import { PipelineStage } from "mongoose"; + +import { optionalAuthMiddleware } from "../../../../services/auth/middleware.ts"; +import { AppContext, AppEnv } from "../../../../main.ts"; +import type * as SoSprkActorDefs from "../../../../lexicon/types/so/sprk/actor/defs.ts"; + +export const createGetFollowsRouter = (ctx: AppContext) => { + const router = new Hono(); + + router.get( + "/xrpc/so.sprk.graph.getFollows", + optionalAuthMiddleware, + async (c) => { + const actor = c.req.query("actor"); + const limit = parseInt(c.req.query("limit") ?? "50"); + const cursor = c.req.query("cursor"); + const viewerDid = c.var.did as string | undefined; + + if (!actor) { + return c.json({ error: "Actor is required" }, 400); + } + + // Validate limit + if (limit < 1 || limit > 100) { + return c.json({ error: "Limit must be between 1 and 100" }, 400); + } + + let follows = []; + + // If user is authenticated, respect their follow preferences + if (viewerDid) { + const viewerPref = await ctx.db.models.UserPreference.findOne({ + userDid: viewerDid, + }); + const followType = viewerPref?.followMode || "sprk"; + + // Build query with the user's preferred follow type + const query: { + authorDid: string; + type: string; + _id?: { $gt: string }; + } = { + authorDid: actor, + type: followType, + }; + + if (cursor) { + query._id = { $gt: cursor }; + } + + follows = await ctx.db.models.Follow.find(query) + .sort({ _id: 1 }) + .limit(limit) + .lean(); + } else { + // For unauthenticated users, get all follow types without duplicates + // We use aggregation to get distinct follows by subject + const pipelineStages: PipelineStage[] = [ + { $match: { authorDid: actor } }, + ]; + + if (cursor) { + pipelineStages.push({ $match: { _id: { $gt: cursor } } }); + } + + // Group by subject to avoid duplicates + pipelineStages.push( + { $sort: { _id: 1 } }, + { + $group: { + _id: "$subject", + doc: { $first: "$$ROOT" }, + }, + }, + { $replaceRoot: { newRoot: "$doc" } }, + { $sort: { _id: 1 } }, + { $limit: limit }, + ); + + follows = await ctx.db.models.Follow.aggregate(pipelineStages); + } + + // Get next cursor + const nextCursor = follows.length === limit + ? follows[follows.length - 1]._id + : undefined; + + // Get profile views for each follow + const profileViews = await Promise.all( + follows.map(async (follow) => { + const profile = await ctx.db.models.Profile.findOne({ + authorDid: follow.subject, + }); + // Basic profile view with just DID + const basicProfileView: SoSprkActorDefs.ProfileView = { + $type: "so.sprk.actor.defs#profileView", + did: follow.authorDid, + handle: follow.authorHandle, + viewer: { + $type: "so.sprk.actor.defs#viewerState", + followedBy: follow.uri, + }, + }; + + // If we found a profile, add the additional fields + if (profile) { + return { + ...basicProfileView, + handle: profile.authorHandle, + displayName: profile.displayName, + description: profile.description, + avatar: profile.avatar?.ref?.$link, + indexedAt: profile.indexedAt, + createdAt: profile.createdAt, + }; + } + + return basicProfileView; + }), + ); + + // Get subject profile if it exists + const subjectProfile = await ctx.db.models.Profile.findOne({ + authorDid: actor, + }); + const subjectProfileView: SoSprkActorDefs.ProfileView = { + $type: "so.sprk.actor.defs#profileView", + did: actor, + handle: "unknown", + }; + // If we found the subject profile, add the additional fields + if (subjectProfile) { + Object.assign(subjectProfileView, { + handle: subjectProfile.authorHandle, + displayName: subjectProfile.displayName, + description: subjectProfile.description, + avatar: subjectProfile.avatar?.ref?.$link, + indexedAt: subjectProfile.indexedAt, + createdAt: subjectProfile.createdAt, + }); + } else { + let handle = null; + try { + if (actor) { + const didData = await ctx.resolver.resolveDidToDidDoc(actor); + handle = didData.handle; + } + } catch (error) { + ctx.logger.warn( + { did: actor, error: (error as Error).message }, + "Failed to resolve DID to handle", + ); + } + Object.assign(subjectProfileView, { + handle: handle ?? "unknown", + }); + } + + return c.json({ + subject: subjectProfileView, + follows: profileViews, + cursor: nextCursor, + }); + }, + ); + + return router; +}; diff --git a/services/appview/compose.dev.yaml b/services/appview/compose.dev.yaml index f4c2502..00f8c3b 100644 --- a/services/appview/compose.dev.yaml +++ b/services/appview/compose.dev.yaml @@ -32,18 +32,24 @@ services: ADMIN_PASSWORD: "00000000000000000000000000000000" ports: - "4000:3000" - volumes: - - ./src:/app/src - - ./tsconfig.json:/app/tsconfig.json depends_on: db: condition: service_healthy develop: watch: - - path: ./src - action: sync+restart - target: /app/src - - path: ./package.json - action: rebuild - target: /app/package.json + - path: ./api + action: sync + target: /app/api + - path: ./lexicon + action: sync + target: /app/lexicon + - path: ./services + action: sync + target: /app/services + - path: ./utils + action: sync + target: /app/utils + - path: ./main.ts + action: sync + target: /app/main.ts restart: unless-stopped diff --git a/services/appview/deno.json b/services/appview/deno.json new file mode 100644 index 0000000..5c10ba7 --- /dev/null +++ b/services/appview/deno.json @@ -0,0 +1,33 @@ +{ + "tasks": { + "dev": "deno run --allow-net --allow-env --allow-sys --allow-read --allow-ffi --watch main.ts", + "codegen": "lex gen-server --yes ./lexicon ../../lexicons/com/atproto/*/* ../../lexicons/so/sprk/*/*", + "start": "deno run --allow-net --allow-env --allow-sys --allow-read --allow-ffi main.ts", + "docker-dev": "docker compose -f compose.dev.yaml up --build --watch" + }, + "imports": { + "hono": "jsr:@hono/hono@^4.7.10", + "@std/encoding": "jsr:@std/encoding@1", + "@atproto/api": "npm:@atproto/api@^0.14.9", + "@atproto/common": "npm:@atproto/common@^0.4.8", + "@atproto/crypto": "npm:@atproto/crypto@^0.4.4", + "@atproto/identity": "npm:@atproto/identity@^0.4.6", + "@atproto/lexicon": "npm:@atproto/lexicon@^0.4.8", + "@atproto/syntax": "npm:@atproto/syntax@^0.3.4", + "@atproto/xrpc-server": "npm:@atproto/xrpc-server@^0.7.12", + "express": "npm:express@^4.21.2", + "mongoose": "npm:mongoose@^8.12.1", + "multiformats": "npm:multiformats@^9.9.0", + "pino": "npm:pino@^9.6.0" + }, + "compilerOptions": { + "jsx": "precompile", + "jsxImportSource": "hono/jsx" + }, + "lint": { + "exclude": ["lexicon/"] + }, + "fmt": { + "exclude": ["lexicon/"] + } +} diff --git a/services/appview/src/lexicon/index.ts b/services/appview/lexicon/index.ts similarity index 50% rename from services/appview/src/lexicon/index.ts rename to services/appview/lexicon/index.ts index 2d451de..32ef411 100644 --- a/services/appview/src/lexicon/index.ts +++ b/services/appview/lexicon/index.ts @@ -2,243 +2,243 @@ * GENERATED CODE - DO NOT MODIFY */ import { + AuthVerifier, createServer as createXrpcServer, - Server as XrpcServer, Options as XrpcOptions, - AuthVerifier, + Server as XrpcServer, StreamAuthVerifier, -} from '@atproto/xrpc-server' -import { schemas } from './lexicons.js' -import * as ComAtprotoAdminDeleteAccount from './types/com/atproto/admin/deleteAccount.js' -import * as ComAtprotoAdminDisableAccountInvites from './types/com/atproto/admin/disableAccountInvites.js' -import * as ComAtprotoAdminDisableInviteCodes from './types/com/atproto/admin/disableInviteCodes.js' -import * as ComAtprotoAdminEnableAccountInvites from './types/com/atproto/admin/enableAccountInvites.js' -import * as ComAtprotoAdminGetAccountInfo from './types/com/atproto/admin/getAccountInfo.js' -import * as ComAtprotoAdminGetAccountInfos from './types/com/atproto/admin/getAccountInfos.js' -import * as ComAtprotoAdminGetInviteCodes from './types/com/atproto/admin/getInviteCodes.js' -import * as ComAtprotoAdminGetSubjectStatus from './types/com/atproto/admin/getSubjectStatus.js' -import * as ComAtprotoAdminSearchAccounts from './types/com/atproto/admin/searchAccounts.js' -import * as ComAtprotoAdminSendEmail from './types/com/atproto/admin/sendEmail.js' -import * as ComAtprotoAdminUpdateAccountEmail from './types/com/atproto/admin/updateAccountEmail.js' -import * as ComAtprotoAdminUpdateAccountHandle from './types/com/atproto/admin/updateAccountHandle.js' -import * as ComAtprotoAdminUpdateAccountPassword from './types/com/atproto/admin/updateAccountPassword.js' -import * as ComAtprotoAdminUpdateSubjectStatus from './types/com/atproto/admin/updateSubjectStatus.js' -import * as ComAtprotoIdentityGetRecommendedDidCredentials from './types/com/atproto/identity/getRecommendedDidCredentials.js' -import * as ComAtprotoIdentityRequestPlcOperationSignature from './types/com/atproto/identity/requestPlcOperationSignature.js' -import * as ComAtprotoIdentityResolveHandle from './types/com/atproto/identity/resolveHandle.js' -import * as ComAtprotoIdentitySignPlcOperation from './types/com/atproto/identity/signPlcOperation.js' -import * as ComAtprotoIdentitySubmitPlcOperation from './types/com/atproto/identity/submitPlcOperation.js' -import * as ComAtprotoIdentityUpdateHandle from './types/com/atproto/identity/updateHandle.js' -import * as ComAtprotoLabelQueryLabels from './types/com/atproto/label/queryLabels.js' -import * as ComAtprotoLabelSubscribeLabels from './types/com/atproto/label/subscribeLabels.js' -import * as ComAtprotoModerationCreateReport from './types/com/atproto/moderation/createReport.js' -import * as ComAtprotoRepoApplyWrites from './types/com/atproto/repo/applyWrites.js' -import * as ComAtprotoRepoCreateRecord from './types/com/atproto/repo/createRecord.js' -import * as ComAtprotoRepoDeleteRecord from './types/com/atproto/repo/deleteRecord.js' -import * as ComAtprotoRepoDescribeRepo from './types/com/atproto/repo/describeRepo.js' -import * as ComAtprotoRepoGetRecord from './types/com/atproto/repo/getRecord.js' -import * as ComAtprotoRepoImportRepo from './types/com/atproto/repo/importRepo.js' -import * as ComAtprotoRepoListMissingBlobs from './types/com/atproto/repo/listMissingBlobs.js' -import * as ComAtprotoRepoListRecords from './types/com/atproto/repo/listRecords.js' -import * as ComAtprotoRepoPutRecord from './types/com/atproto/repo/putRecord.js' -import * as ComAtprotoRepoUploadBlob from './types/com/atproto/repo/uploadBlob.js' -import * as ComAtprotoServerActivateAccount from './types/com/atproto/server/activateAccount.js' -import * as ComAtprotoServerCheckAccountStatus from './types/com/atproto/server/checkAccountStatus.js' -import * as ComAtprotoServerConfirmEmail from './types/com/atproto/server/confirmEmail.js' -import * as ComAtprotoServerCreateAccount from './types/com/atproto/server/createAccount.js' -import * as ComAtprotoServerCreateAppPassword from './types/com/atproto/server/createAppPassword.js' -import * as ComAtprotoServerCreateInviteCode from './types/com/atproto/server/createInviteCode.js' -import * as ComAtprotoServerCreateInviteCodes from './types/com/atproto/server/createInviteCodes.js' -import * as ComAtprotoServerCreateSession from './types/com/atproto/server/createSession.js' -import * as ComAtprotoServerDeactivateAccount from './types/com/atproto/server/deactivateAccount.js' -import * as ComAtprotoServerDeleteAccount from './types/com/atproto/server/deleteAccount.js' -import * as ComAtprotoServerDeleteSession from './types/com/atproto/server/deleteSession.js' -import * as ComAtprotoServerDescribeServer from './types/com/atproto/server/describeServer.js' -import * as ComAtprotoServerGetAccountInviteCodes from './types/com/atproto/server/getAccountInviteCodes.js' -import * as ComAtprotoServerGetServiceAuth from './types/com/atproto/server/getServiceAuth.js' -import * as ComAtprotoServerGetSession from './types/com/atproto/server/getSession.js' -import * as ComAtprotoServerListAppPasswords from './types/com/atproto/server/listAppPasswords.js' -import * as ComAtprotoServerRefreshSession from './types/com/atproto/server/refreshSession.js' -import * as ComAtprotoServerRequestAccountDelete from './types/com/atproto/server/requestAccountDelete.js' -import * as ComAtprotoServerRequestEmailConfirmation from './types/com/atproto/server/requestEmailConfirmation.js' -import * as ComAtprotoServerRequestEmailUpdate from './types/com/atproto/server/requestEmailUpdate.js' -import * as ComAtprotoServerRequestPasswordReset from './types/com/atproto/server/requestPasswordReset.js' -import * as ComAtprotoServerReserveSigningKey from './types/com/atproto/server/reserveSigningKey.js' -import * as ComAtprotoServerResetPassword from './types/com/atproto/server/resetPassword.js' -import * as ComAtprotoServerRevokeAppPassword from './types/com/atproto/server/revokeAppPassword.js' -import * as ComAtprotoServerUpdateEmail from './types/com/atproto/server/updateEmail.js' -import * as ComAtprotoSyncGetBlob from './types/com/atproto/sync/getBlob.js' -import * as ComAtprotoSyncGetBlocks from './types/com/atproto/sync/getBlocks.js' -import * as ComAtprotoSyncGetCheckout from './types/com/atproto/sync/getCheckout.js' -import * as ComAtprotoSyncGetHead from './types/com/atproto/sync/getHead.js' -import * as ComAtprotoSyncGetLatestCommit from './types/com/atproto/sync/getLatestCommit.js' -import * as ComAtprotoSyncGetRecord from './types/com/atproto/sync/getRecord.js' -import * as ComAtprotoSyncGetRepo from './types/com/atproto/sync/getRepo.js' -import * as ComAtprotoSyncGetRepoStatus from './types/com/atproto/sync/getRepoStatus.js' -import * as ComAtprotoSyncListBlobs from './types/com/atproto/sync/listBlobs.js' -import * as ComAtprotoSyncListReposByCollection from './types/com/atproto/sync/listReposByCollection.js' -import * as ComAtprotoSyncListRepos from './types/com/atproto/sync/listRepos.js' -import * as ComAtprotoSyncNotifyOfUpdate from './types/com/atproto/sync/notifyOfUpdate.js' -import * as ComAtprotoSyncRequestCrawl from './types/com/atproto/sync/requestCrawl.js' -import * as ComAtprotoSyncSubscribeRepos from './types/com/atproto/sync/subscribeRepos.js' -import * as ComAtprotoTempAddReservedHandle from './types/com/atproto/temp/addReservedHandle.js' -import * as ComAtprotoTempCheckSignupQueue from './types/com/atproto/temp/checkSignupQueue.js' -import * as ComAtprotoTempFetchLabels from './types/com/atproto/temp/fetchLabels.js' -import * as ComAtprotoTempRequestPhoneVerification from './types/com/atproto/temp/requestPhoneVerification.js' -import * as SoSprkActorGetPreferences from './types/so/sprk/actor/getPreferences.js' -import * as SoSprkActorGetProfile from './types/so/sprk/actor/getProfile.js' -import * as SoSprkActorGetProfiles from './types/so/sprk/actor/getProfiles.js' -import * as SoSprkActorGetSuggestions from './types/so/sprk/actor/getSuggestions.js' -import * as SoSprkActorPutPreferences from './types/so/sprk/actor/putPreferences.js' -import * as SoSprkActorSearchActors from './types/so/sprk/actor/searchActors.js' -import * as SoSprkActorSearchActorsTypeahead from './types/so/sprk/actor/searchActorsTypeahead.js' -import * as SoSprkFeedDescribeFeedGenerator from './types/so/sprk/feed/describeFeedGenerator.js' -import * as SoSprkFeedGetActorFeeds from './types/so/sprk/feed/getActorFeeds.js' -import * as SoSprkFeedGetActorLikes from './types/so/sprk/feed/getActorLikes.js' -import * as SoSprkFeedGetActorLooks from './types/so/sprk/feed/getActorLooks.js' -import * as SoSprkFeedGetAuthorFeed from './types/so/sprk/feed/getAuthorFeed.js' -import * as SoSprkFeedGetFeedGenerator from './types/so/sprk/feed/getFeedGenerator.js' -import * as SoSprkFeedGetFeedGenerators from './types/so/sprk/feed/getFeedGenerators.js' -import * as SoSprkFeedGetFeed from './types/so/sprk/feed/getFeed.js' -import * as SoSprkFeedGetFeedSkeleton from './types/so/sprk/feed/getFeedSkeleton.js' -import * as SoSprkFeedGetLikes from './types/so/sprk/feed/getLikes.js' -import * as SoSprkFeedGetListFeed from './types/so/sprk/feed/getListFeed.js' -import * as SoSprkFeedGetLooks from './types/so/sprk/feed/getLooks.js' -import * as SoSprkFeedGetPosts from './types/so/sprk/feed/getPosts.js' -import * as SoSprkFeedGetPostThread from './types/so/sprk/feed/getPostThread.js' -import * as SoSprkFeedGetQuotes from './types/so/sprk/feed/getQuotes.js' -import * as SoSprkFeedGetRepostedBy from './types/so/sprk/feed/getRepostedBy.js' -import * as SoSprkFeedGetSuggestedFeeds from './types/so/sprk/feed/getSuggestedFeeds.js' -import * as SoSprkFeedGetTimeline from './types/so/sprk/feed/getTimeline.js' -import * as SoSprkFeedSearchPosts from './types/so/sprk/feed/searchPosts.js' -import * as SoSprkFeedSendInteractions from './types/so/sprk/feed/sendInteractions.js' -import * as SoSprkGraphGetActorStarterPacks from './types/so/sprk/graph/getActorStarterPacks.js' -import * as SoSprkGraphGetBlocks from './types/so/sprk/graph/getBlocks.js' -import * as SoSprkGraphGetFollowers from './types/so/sprk/graph/getFollowers.js' -import * as SoSprkGraphGetFollows from './types/so/sprk/graph/getFollows.js' -import * as SoSprkGraphGetKnownFollowers from './types/so/sprk/graph/getKnownFollowers.js' -import * as SoSprkGraphGetListBlocks from './types/so/sprk/graph/getListBlocks.js' -import * as SoSprkGraphGetList from './types/so/sprk/graph/getList.js' -import * as SoSprkGraphGetListMutes from './types/so/sprk/graph/getListMutes.js' -import * as SoSprkGraphGetLists from './types/so/sprk/graph/getLists.js' -import * as SoSprkGraphGetMutes from './types/so/sprk/graph/getMutes.js' -import * as SoSprkGraphGetRelationships from './types/so/sprk/graph/getRelationships.js' -import * as SoSprkGraphGetStarterPack from './types/so/sprk/graph/getStarterPack.js' -import * as SoSprkGraphGetStarterPacks from './types/so/sprk/graph/getStarterPacks.js' -import * as SoSprkGraphGetSuggestedFollowsByActor from './types/so/sprk/graph/getSuggestedFollowsByActor.js' -import * as SoSprkGraphMuteActor from './types/so/sprk/graph/muteActor.js' -import * as SoSprkGraphMuteActorList from './types/so/sprk/graph/muteActorList.js' -import * as SoSprkGraphMuteThread from './types/so/sprk/graph/muteThread.js' -import * as SoSprkGraphSearchStarterPacks from './types/so/sprk/graph/searchStarterPacks.js' -import * as SoSprkGraphUnmuteActor from './types/so/sprk/graph/unmuteActor.js' -import * as SoSprkGraphUnmuteActorList from './types/so/sprk/graph/unmuteActorList.js' -import * as SoSprkGraphUnmuteThread from './types/so/sprk/graph/unmuteThread.js' -import * as SoSprkLabelerGetServices from './types/so/sprk/labeler/getServices.js' -import * as SoSprkNotificationGetUnreadCount from './types/so/sprk/notification/getUnreadCount.js' -import * as SoSprkNotificationListNotifications from './types/so/sprk/notification/listNotifications.js' -import * as SoSprkNotificationPutPreferences from './types/so/sprk/notification/putPreferences.js' -import * as SoSprkNotificationRegisterPush from './types/so/sprk/notification/registerPush.js' -import * as SoSprkNotificationUpdateSeen from './types/so/sprk/notification/updateSeen.js' -import * as SoSprkUnspeccedGetConfig from './types/so/sprk/unspecced/getConfig.js' -import * as SoSprkUnspeccedGetPopularFeedGenerators from './types/so/sprk/unspecced/getPopularFeedGenerators.js' -import * as SoSprkUnspeccedGetSuggestionsSkeleton from './types/so/sprk/unspecced/getSuggestionsSkeleton.js' -import * as SoSprkUnspeccedGetTaggedSuggestions from './types/so/sprk/unspecced/getTaggedSuggestions.js' -import * as SoSprkUnspeccedGetTrendingTopics from './types/so/sprk/unspecced/getTrendingTopics.js' -import * as SoSprkUnspeccedSearchActorsSkeleton from './types/so/sprk/unspecced/searchActorsSkeleton.js' -import * as SoSprkUnspeccedSearchPostsSkeleton from './types/so/sprk/unspecced/searchPostsSkeleton.js' -import * as SoSprkUnspeccedSearchStarterPacksSkeleton from './types/so/sprk/unspecced/searchStarterPacksSkeleton.js' -import * as SoSprkVideoGetJobStatus from './types/so/sprk/video/getJobStatus.js' -import * as SoSprkVideoGetUploadLimits from './types/so/sprk/video/getUploadLimits.js' -import * as SoSprkVideoUploadVideo from './types/so/sprk/video/uploadVideo.js' +} from "@atproto/xrpc-server"; +import { schemas } from "./lexicons.ts"; +import * as ComAtprotoAdminDeleteAccount from "./types/com/atproto/admin/deleteAccount.ts"; +import * as ComAtprotoAdminDisableAccountInvites from "./types/com/atproto/admin/disableAccountInvites.ts"; +import * as ComAtprotoAdminDisableInviteCodes from "./types/com/atproto/admin/disableInviteCodes.ts"; +import * as ComAtprotoAdminEnableAccountInvites from "./types/com/atproto/admin/enableAccountInvites.ts"; +import * as ComAtprotoAdminGetAccountInfo from "./types/com/atproto/admin/getAccountInfo.ts"; +import * as ComAtprotoAdminGetAccountInfos from "./types/com/atproto/admin/getAccountInfos.ts"; +import * as ComAtprotoAdminGetInviteCodes from "./types/com/atproto/admin/getInviteCodes.ts"; +import * as ComAtprotoAdminGetSubjectStatus from "./types/com/atproto/admin/getSubjectStatus.ts"; +import * as ComAtprotoAdminSearchAccounts from "./types/com/atproto/admin/searchAccounts.ts"; +import * as ComAtprotoAdminSendEmail from "./types/com/atproto/admin/sendEmail.ts"; +import * as ComAtprotoAdminUpdateAccountEmail from "./types/com/atproto/admin/updateAccountEmail.ts"; +import * as ComAtprotoAdminUpdateAccountHandle from "./types/com/atproto/admin/updateAccountHandle.ts"; +import * as ComAtprotoAdminUpdateAccountPassword from "./types/com/atproto/admin/updateAccountPassword.ts"; +import * as ComAtprotoAdminUpdateSubjectStatus from "./types/com/atproto/admin/updateSubjectStatus.ts"; +import * as ComAtprotoIdentityGetRecommendedDidCredentials from "./types/com/atproto/identity/getRecommendedDidCredentials.ts"; +import * as ComAtprotoIdentityRequestPlcOperationSignature from "./types/com/atproto/identity/requestPlcOperationSignature.ts"; +import * as ComAtprotoIdentityResolveHandle from "./types/com/atproto/identity/resolveHandle.ts"; +import * as ComAtprotoIdentitySignPlcOperation from "./types/com/atproto/identity/signPlcOperation.ts"; +import * as ComAtprotoIdentitySubmitPlcOperation from "./types/com/atproto/identity/submitPlcOperation.ts"; +import * as ComAtprotoIdentityUpdateHandle from "./types/com/atproto/identity/updateHandle.ts"; +import * as ComAtprotoLabelQueryLabels from "./types/com/atproto/label/queryLabels.ts"; +import * as ComAtprotoLabelSubscribeLabels from "./types/com/atproto/label/subscribeLabels.ts"; +import * as ComAtprotoModerationCreateReport from "./types/com/atproto/moderation/createReport.ts"; +import * as ComAtprotoRepoApplyWrites from "./types/com/atproto/repo/applyWrites.ts"; +import * as ComAtprotoRepoCreateRecord from "./types/com/atproto/repo/createRecord.ts"; +import * as ComAtprotoRepoDeleteRecord from "./types/com/atproto/repo/deleteRecord.ts"; +import * as ComAtprotoRepoDescribeRepo from "./types/com/atproto/repo/describeRepo.ts"; +import * as ComAtprotoRepoGetRecord from "./types/com/atproto/repo/getRecord.ts"; +import * as ComAtprotoRepoImportRepo from "./types/com/atproto/repo/importRepo.ts"; +import * as ComAtprotoRepoListMissingBlobs from "./types/com/atproto/repo/listMissingBlobs.ts"; +import * as ComAtprotoRepoListRecords from "./types/com/atproto/repo/listRecords.ts"; +import * as ComAtprotoRepoPutRecord from "./types/com/atproto/repo/putRecord.ts"; +import * as ComAtprotoRepoUploadBlob from "./types/com/atproto/repo/uploadBlob.ts"; +import * as ComAtprotoServerActivateAccount from "./types/com/atproto/server/activateAccount.ts"; +import * as ComAtprotoServerCheckAccountStatus from "./types/com/atproto/server/checkAccountStatus.ts"; +import * as ComAtprotoServerConfirmEmail from "./types/com/atproto/server/confirmEmail.ts"; +import * as ComAtprotoServerCreateAccount from "./types/com/atproto/server/createAccount.ts"; +import * as ComAtprotoServerCreateAppPassword from "./types/com/atproto/server/createAppPassword.ts"; +import * as ComAtprotoServerCreateInviteCode from "./types/com/atproto/server/createInviteCode.ts"; +import * as ComAtprotoServerCreateInviteCodes from "./types/com/atproto/server/createInviteCodes.ts"; +import * as ComAtprotoServerCreateSession from "./types/com/atproto/server/createSession.ts"; +import * as ComAtprotoServerDeactivateAccount from "./types/com/atproto/server/deactivateAccount.ts"; +import * as ComAtprotoServerDeleteAccount from "./types/com/atproto/server/deleteAccount.ts"; +import * as ComAtprotoServerDeleteSession from "./types/com/atproto/server/deleteSession.ts"; +import * as ComAtprotoServerDescribeServer from "./types/com/atproto/server/describeServer.ts"; +import * as ComAtprotoServerGetAccountInviteCodes from "./types/com/atproto/server/getAccountInviteCodes.ts"; +import * as ComAtprotoServerGetServiceAuth from "./types/com/atproto/server/getServiceAuth.ts"; +import * as ComAtprotoServerGetSession from "./types/com/atproto/server/getSession.ts"; +import * as ComAtprotoServerListAppPasswords from "./types/com/atproto/server/listAppPasswords.ts"; +import * as ComAtprotoServerRefreshSession from "./types/com/atproto/server/refreshSession.ts"; +import * as ComAtprotoServerRequestAccountDelete from "./types/com/atproto/server/requestAccountDelete.ts"; +import * as ComAtprotoServerRequestEmailConfirmation from "./types/com/atproto/server/requestEmailConfirmation.ts"; +import * as ComAtprotoServerRequestEmailUpdate from "./types/com/atproto/server/requestEmailUpdate.ts"; +import * as ComAtprotoServerRequestPasswordReset from "./types/com/atproto/server/requestPasswordReset.ts"; +import * as ComAtprotoServerReserveSigningKey from "./types/com/atproto/server/reserveSigningKey.ts"; +import * as ComAtprotoServerResetPassword from "./types/com/atproto/server/resetPassword.ts"; +import * as ComAtprotoServerRevokeAppPassword from "./types/com/atproto/server/revokeAppPassword.ts"; +import * as ComAtprotoServerUpdateEmail from "./types/com/atproto/server/updateEmail.ts"; +import * as ComAtprotoSyncGetBlob from "./types/com/atproto/sync/getBlob.ts"; +import * as ComAtprotoSyncGetBlocks from "./types/com/atproto/sync/getBlocks.ts"; +import * as ComAtprotoSyncGetCheckout from "./types/com/atproto/sync/getCheckout.ts"; +import * as ComAtprotoSyncGetHead from "./types/com/atproto/sync/getHead.ts"; +import * as ComAtprotoSyncGetLatestCommit from "./types/com/atproto/sync/getLatestCommit.ts"; +import * as ComAtprotoSyncGetRecord from "./types/com/atproto/sync/getRecord.ts"; +import * as ComAtprotoSyncGetRepo from "./types/com/atproto/sync/getRepo.ts"; +import * as ComAtprotoSyncGetRepoStatus from "./types/com/atproto/sync/getRepoStatus.ts"; +import * as ComAtprotoSyncListBlobs from "./types/com/atproto/sync/listBlobs.ts"; +import * as ComAtprotoSyncListReposByCollection from "./types/com/atproto/sync/listReposByCollection.ts"; +import * as ComAtprotoSyncListRepos from "./types/com/atproto/sync/listRepos.ts"; +import * as ComAtprotoSyncNotifyOfUpdate from "./types/com/atproto/sync/notifyOfUpdate.ts"; +import * as ComAtprotoSyncRequestCrawl from "./types/com/atproto/sync/requestCrawl.ts"; +import * as ComAtprotoSyncSubscribeRepos from "./types/com/atproto/sync/subscribeRepos.ts"; +import * as ComAtprotoTempAddReservedHandle from "./types/com/atproto/temp/addReservedHandle.ts"; +import * as ComAtprotoTempCheckSignupQueue from "./types/com/atproto/temp/checkSignupQueue.ts"; +import * as ComAtprotoTempFetchLabels from "./types/com/atproto/temp/fetchLabels.ts"; +import * as ComAtprotoTempRequestPhoneVerification from "./types/com/atproto/temp/requestPhoneVerification.ts"; +import * as SoSprkActorGetPreferences from "./types/so/sprk/actor/getPreferences.ts"; +import * as SoSprkActorGetProfile from "./types/so/sprk/actor/getProfile.ts"; +import * as SoSprkActorGetProfiles from "./types/so/sprk/actor/getProfiles.ts"; +import * as SoSprkActorGetSuggestions from "./types/so/sprk/actor/getSuggestions.ts"; +import * as SoSprkActorPutPreferences from "./types/so/sprk/actor/putPreferences.ts"; +import * as SoSprkActorSearchActors from "./types/so/sprk/actor/searchActors.ts"; +import * as SoSprkActorSearchActorsTypeahead from "./types/so/sprk/actor/searchActorsTypeahead.ts"; +import * as SoSprkFeedDescribeFeedGenerator from "./types/so/sprk/feed/describeFeedGenerator.ts"; +import * as SoSprkFeedGetActorFeeds from "./types/so/sprk/feed/getActorFeeds.ts"; +import * as SoSprkFeedGetActorLikes from "./types/so/sprk/feed/getActorLikes.ts"; +import * as SoSprkFeedGetActorLooks from "./types/so/sprk/feed/getActorLooks.ts"; +import * as SoSprkFeedGetAuthorFeed from "./types/so/sprk/feed/getAuthorFeed.ts"; +import * as SoSprkFeedGetFeedGenerator from "./types/so/sprk/feed/getFeedGenerator.ts"; +import * as SoSprkFeedGetFeedGenerators from "./types/so/sprk/feed/getFeedGenerators.ts"; +import * as SoSprkFeedGetFeed from "./types/so/sprk/feed/getFeed.ts"; +import * as SoSprkFeedGetFeedSkeleton from "./types/so/sprk/feed/getFeedSkeleton.ts"; +import * as SoSprkFeedGetLikes from "./types/so/sprk/feed/getLikes.ts"; +import * as SoSprkFeedGetListFeed from "./types/so/sprk/feed/getListFeed.ts"; +import * as SoSprkFeedGetLooks from "./types/so/sprk/feed/getLooks.ts"; +import * as SoSprkFeedGetPosts from "./types/so/sprk/feed/getPosts.ts"; +import * as SoSprkFeedGetPostThread from "./types/so/sprk/feed/getPostThread.ts"; +import * as SoSprkFeedGetQuotes from "./types/so/sprk/feed/getQuotes.ts"; +import * as SoSprkFeedGetRepostedBy from "./types/so/sprk/feed/getRepostedBy.ts"; +import * as SoSprkFeedGetSuggestedFeeds from "./types/so/sprk/feed/getSuggestedFeeds.ts"; +import * as SoSprkFeedGetTimeline from "./types/so/sprk/feed/getTimeline.ts"; +import * as SoSprkFeedSearchPosts from "./types/so/sprk/feed/searchPosts.ts"; +import * as SoSprkFeedSendInteractions from "./types/so/sprk/feed/sendInteractions.ts"; +import * as SoSprkGraphGetActorStarterPacks from "./types/so/sprk/graph/getActorStarterPacks.ts"; +import * as SoSprkGraphGetBlocks from "./types/so/sprk/graph/getBlocks.ts"; +import * as SoSprkGraphGetFollowers from "./types/so/sprk/graph/getFollowers.ts"; +import * as SoSprkGraphGetFollows from "./types/so/sprk/graph/getFollows.ts"; +import * as SoSprkGraphGetKnownFollowers from "./types/so/sprk/graph/getKnownFollowers.ts"; +import * as SoSprkGraphGetListBlocks from "./types/so/sprk/graph/getListBlocks.ts"; +import * as SoSprkGraphGetList from "./types/so/sprk/graph/getList.ts"; +import * as SoSprkGraphGetListMutes from "./types/so/sprk/graph/getListMutes.ts"; +import * as SoSprkGraphGetLists from "./types/so/sprk/graph/getLists.ts"; +import * as SoSprkGraphGetMutes from "./types/so/sprk/graph/getMutes.ts"; +import * as SoSprkGraphGetRelationships from "./types/so/sprk/graph/getRelationships.ts"; +import * as SoSprkGraphGetStarterPack from "./types/so/sprk/graph/getStarterPack.ts"; +import * as SoSprkGraphGetStarterPacks from "./types/so/sprk/graph/getStarterPacks.ts"; +import * as SoSprkGraphGetSuggestedFollowsByActor from "./types/so/sprk/graph/getSuggestedFollowsByActor.ts"; +import * as SoSprkGraphMuteActor from "./types/so/sprk/graph/muteActor.ts"; +import * as SoSprkGraphMuteActorList from "./types/so/sprk/graph/muteActorList.ts"; +import * as SoSprkGraphMuteThread from "./types/so/sprk/graph/muteThread.ts"; +import * as SoSprkGraphSearchStarterPacks from "./types/so/sprk/graph/searchStarterPacks.ts"; +import * as SoSprkGraphUnmuteActor from "./types/so/sprk/graph/unmuteActor.ts"; +import * as SoSprkGraphUnmuteActorList from "./types/so/sprk/graph/unmuteActorList.ts"; +import * as SoSprkGraphUnmuteThread from "./types/so/sprk/graph/unmuteThread.ts"; +import * as SoSprkLabelerGetServices from "./types/so/sprk/labeler/getServices.ts"; +import * as SoSprkNotificationGetUnreadCount from "./types/so/sprk/notification/getUnreadCount.ts"; +import * as SoSprkNotificationListNotifications from "./types/so/sprk/notification/listNotifications.ts"; +import * as SoSprkNotificationPutPreferences from "./types/so/sprk/notification/putPreferences.ts"; +import * as SoSprkNotificationRegisterPush from "./types/so/sprk/notification/registerPush.ts"; +import * as SoSprkNotificationUpdateSeen from "./types/so/sprk/notification/updateSeen.ts"; +import * as SoSprkUnspeccedGetConfig from "./types/so/sprk/unspecced/getConfig.ts"; +import * as SoSprkUnspeccedGetPopularFeedGenerators from "./types/so/sprk/unspecced/getPopularFeedGenerators.ts"; +import * as SoSprkUnspeccedGetSuggestionsSkeleton from "./types/so/sprk/unspecced/getSuggestionsSkeleton.ts"; +import * as SoSprkUnspeccedGetTaggedSuggestions from "./types/so/sprk/unspecced/getTaggedSuggestions.ts"; +import * as SoSprkUnspeccedGetTrendingTopics from "./types/so/sprk/unspecced/getTrendingTopics.ts"; +import * as SoSprkUnspeccedSearchActorsSkeleton from "./types/so/sprk/unspecced/searchActorsSkeleton.ts"; +import * as SoSprkUnspeccedSearchPostsSkeleton from "./types/so/sprk/unspecced/searchPostsSkeleton.ts"; +import * as SoSprkUnspeccedSearchStarterPacksSkeleton from "./types/so/sprk/unspecced/searchStarterPacksSkeleton.ts"; +import * as SoSprkVideoGetJobStatus from "./types/so/sprk/video/getJobStatus.ts"; +import * as SoSprkVideoGetUploadLimits from "./types/so/sprk/video/getUploadLimits.ts"; +import * as SoSprkVideoUploadVideo from "./types/so/sprk/video/uploadVideo.ts"; export const COM_ATPROTO_MODERATION = { - DefsReasonSpam: 'com.atproto.moderation.defs#reasonSpam', - DefsReasonViolation: 'com.atproto.moderation.defs#reasonViolation', - DefsReasonMisleading: 'com.atproto.moderation.defs#reasonMisleading', - DefsReasonSexual: 'com.atproto.moderation.defs#reasonSexual', - DefsReasonRude: 'com.atproto.moderation.defs#reasonRude', - DefsReasonOther: 'com.atproto.moderation.defs#reasonOther', - DefsReasonAppeal: 'com.atproto.moderation.defs#reasonAppeal', -} + DefsReasonSpam: "com.atproto.moderation.defs#reasonSpam", + DefsReasonViolation: "com.atproto.moderation.defs#reasonViolation", + DefsReasonMisleading: "com.atproto.moderation.defs#reasonMisleading", + DefsReasonSexual: "com.atproto.moderation.defs#reasonSexual", + DefsReasonRude: "com.atproto.moderation.defs#reasonRude", + DefsReasonOther: "com.atproto.moderation.defs#reasonOther", + DefsReasonAppeal: "com.atproto.moderation.defs#reasonAppeal", +}; export const SO_SPRK_FEED = { - DefsRequestLess: 'so.sprk.feed.defs#requestLess', - DefsRequestMore: 'so.sprk.feed.defs#requestMore', - DefsClickthroughItem: 'so.sprk.feed.defs#clickthroughItem', - DefsClickthroughAuthor: 'so.sprk.feed.defs#clickthroughAuthor', - DefsClickthroughReposter: 'so.sprk.feed.defs#clickthroughReposter', - DefsClickthroughEmbed: 'so.sprk.feed.defs#clickthroughEmbed', - DefsContentModeUnspecified: 'so.sprk.feed.defs#contentModeUnspecified', - DefsContentModeVideo: 'so.sprk.feed.defs#contentModeVideo', - DefsInteractionSeen: 'so.sprk.feed.defs#interactionSeen', - DefsInteractionLike: 'so.sprk.feed.defs#interactionLike', - DefsInteractionRepost: 'so.sprk.feed.defs#interactionRepost', - DefsInteractionReply: 'so.sprk.feed.defs#interactionReply', - DefsInteractionQuote: 'so.sprk.feed.defs#interactionQuote', - DefsInteractionShare: 'so.sprk.feed.defs#interactionShare', -} + DefsRequestLess: "so.sprk.feed.defs#requestLess", + DefsRequestMore: "so.sprk.feed.defs#requestMore", + DefsClickthroughItem: "so.sprk.feed.defs#clickthroughItem", + DefsClickthroughAuthor: "so.sprk.feed.defs#clickthroughAuthor", + DefsClickthroughReposter: "so.sprk.feed.defs#clickthroughReposter", + DefsClickthroughEmbed: "so.sprk.feed.defs#clickthroughEmbed", + DefsContentModeUnspecified: "so.sprk.feed.defs#contentModeUnspecified", + DefsContentModeVideo: "so.sprk.feed.defs#contentModeVideo", + DefsInteractionSeen: "so.sprk.feed.defs#interactionSeen", + DefsInteractionLike: "so.sprk.feed.defs#interactionLike", + DefsInteractionRepost: "so.sprk.feed.defs#interactionRepost", + DefsInteractionReply: "so.sprk.feed.defs#interactionReply", + DefsInteractionQuote: "so.sprk.feed.defs#interactionQuote", + DefsInteractionShare: "so.sprk.feed.defs#interactionShare", +}; export const SO_SPRK_GRAPH = { - DefsModlist: 'so.sprk.graph.defs#modlist', - DefsCuratelist: 'so.sprk.graph.defs#curatelist', - DefsReferencelist: 'so.sprk.graph.defs#referencelist', -} + DefsModlist: "so.sprk.graph.defs#modlist", + DefsCuratelist: "so.sprk.graph.defs#curatelist", + DefsReferencelist: "so.sprk.graph.defs#referencelist", +}; export function createServer(options?: XrpcOptions): Server { - return new Server(options) + return new Server(options); } export class Server { - xrpc: XrpcServer - com: ComNS - so: SoNS + xrpc: XrpcServer; + com: ComNS; + so: SoNS; constructor(options?: XrpcOptions) { - this.xrpc = createXrpcServer(schemas, options) - this.com = new ComNS(this) - this.so = new SoNS(this) + this.xrpc = createXrpcServer(schemas, options); + this.com = new ComNS(this); + this.so = new SoNS(this); } } export class ComNS { - _server: Server - atproto: ComAtprotoNS + _server: Server; + atproto: ComAtprotoNS; constructor(server: Server) { - this._server = server - this.atproto = new ComAtprotoNS(server) + this._server = server; + this.atproto = new ComAtprotoNS(server); } } export class ComAtprotoNS { - _server: Server - admin: ComAtprotoAdminNS - identity: ComAtprotoIdentityNS - label: ComAtprotoLabelNS - lexicon: ComAtprotoLexiconNS - moderation: ComAtprotoModerationNS - repo: ComAtprotoRepoNS - server: ComAtprotoServerNS - sync: ComAtprotoSyncNS - temp: ComAtprotoTempNS + _server: Server; + admin: ComAtprotoAdminNS; + identity: ComAtprotoIdentityNS; + label: ComAtprotoLabelNS; + lexicon: ComAtprotoLexiconNS; + moderation: ComAtprotoModerationNS; + repo: ComAtprotoRepoNS; + server: ComAtprotoServerNS; + sync: ComAtprotoSyncNS; + temp: ComAtprotoTempNS; constructor(server: Server) { - this._server = server - this.admin = new ComAtprotoAdminNS(server) - this.identity = new ComAtprotoIdentityNS(server) - this.label = new ComAtprotoLabelNS(server) - this.lexicon = new ComAtprotoLexiconNS(server) - this.moderation = new ComAtprotoModerationNS(server) - this.repo = new ComAtprotoRepoNS(server) - this.server = new ComAtprotoServerNS(server) - this.sync = new ComAtprotoSyncNS(server) - this.temp = new ComAtprotoTempNS(server) + this._server = server; + this.admin = new ComAtprotoAdminNS(server); + this.identity = new ComAtprotoIdentityNS(server); + this.label = new ComAtprotoLabelNS(server); + this.lexicon = new ComAtprotoLexiconNS(server); + this.moderation = new ComAtprotoModerationNS(server); + this.repo = new ComAtprotoRepoNS(server); + this.server = new ComAtprotoServerNS(server); + this.sync = new ComAtprotoSyncNS(server); + this.temp = new ComAtprotoTempNS(server); } } export class ComAtprotoAdminNS { - _server: Server + _server: Server; constructor(server: Server) { - this._server = server + this._server = server; } deleteAccount( @@ -248,8 +248,8 @@ export class ComAtprotoAdminNS { ComAtprotoAdminDeleteAccount.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.admin.deleteAccount' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.admin.deleteAccount"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } disableAccountInvites( @@ -259,8 +259,8 @@ export class ComAtprotoAdminNS { ComAtprotoAdminDisableAccountInvites.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.admin.disableAccountInvites' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.admin.disableAccountInvites"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } disableInviteCodes( @@ -270,8 +270,8 @@ export class ComAtprotoAdminNS { ComAtprotoAdminDisableInviteCodes.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.admin.disableInviteCodes' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.admin.disableInviteCodes"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } enableAccountInvites( @@ -281,8 +281,8 @@ export class ComAtprotoAdminNS { ComAtprotoAdminEnableAccountInvites.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.admin.enableAccountInvites' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.admin.enableAccountInvites"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } getAccountInfo( @@ -292,8 +292,8 @@ export class ComAtprotoAdminNS { ComAtprotoAdminGetAccountInfo.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.admin.getAccountInfo' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.admin.getAccountInfo"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } getAccountInfos( @@ -303,8 +303,8 @@ export class ComAtprotoAdminNS { ComAtprotoAdminGetAccountInfos.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.admin.getAccountInfos' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.admin.getAccountInfos"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } getInviteCodes( @@ -314,8 +314,8 @@ export class ComAtprotoAdminNS { ComAtprotoAdminGetInviteCodes.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.admin.getInviteCodes' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.admin.getInviteCodes"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } getSubjectStatus( @@ -325,8 +325,8 @@ export class ComAtprotoAdminNS { ComAtprotoAdminGetSubjectStatus.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.admin.getSubjectStatus' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.admin.getSubjectStatus"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } searchAccounts( @@ -336,8 +336,8 @@ export class ComAtprotoAdminNS { ComAtprotoAdminSearchAccounts.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.admin.searchAccounts' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.admin.searchAccounts"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } sendEmail( @@ -347,8 +347,8 @@ export class ComAtprotoAdminNS { ComAtprotoAdminSendEmail.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.admin.sendEmail' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.admin.sendEmail"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } updateAccountEmail( @@ -358,8 +358,8 @@ export class ComAtprotoAdminNS { ComAtprotoAdminUpdateAccountEmail.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.admin.updateAccountEmail' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.admin.updateAccountEmail"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } updateAccountHandle( @@ -369,8 +369,8 @@ export class ComAtprotoAdminNS { ComAtprotoAdminUpdateAccountHandle.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.admin.updateAccountHandle' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.admin.updateAccountHandle"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } updateAccountPassword( @@ -380,8 +380,8 @@ export class ComAtprotoAdminNS { ComAtprotoAdminUpdateAccountPassword.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.admin.updateAccountPassword' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.admin.updateAccountPassword"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } updateSubjectStatus( @@ -391,16 +391,16 @@ export class ComAtprotoAdminNS { ComAtprotoAdminUpdateSubjectStatus.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.admin.updateSubjectStatus' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.admin.updateSubjectStatus"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } } export class ComAtprotoIdentityNS { - _server: Server + _server: Server; constructor(server: Server) { - this._server = server + this._server = server; } getRecommendedDidCredentials( @@ -412,8 +412,8 @@ export class ComAtprotoIdentityNS { > >, ) { - const nsid = 'com.atproto.identity.getRecommendedDidCredentials' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.identity.getRecommendedDidCredentials"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } requestPlcOperationSignature( @@ -425,8 +425,8 @@ export class ComAtprotoIdentityNS { > >, ) { - const nsid = 'com.atproto.identity.requestPlcOperationSignature' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.identity.requestPlcOperationSignature"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } resolveHandle( @@ -436,8 +436,8 @@ export class ComAtprotoIdentityNS { ComAtprotoIdentityResolveHandle.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.identity.resolveHandle' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.identity.resolveHandle"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } signPlcOperation( @@ -447,8 +447,8 @@ export class ComAtprotoIdentityNS { ComAtprotoIdentitySignPlcOperation.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.identity.signPlcOperation' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.identity.signPlcOperation"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } submitPlcOperation( @@ -458,8 +458,8 @@ export class ComAtprotoIdentityNS { ComAtprotoIdentitySubmitPlcOperation.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.identity.submitPlcOperation' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.identity.submitPlcOperation"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } updateHandle( @@ -469,16 +469,16 @@ export class ComAtprotoIdentityNS { ComAtprotoIdentityUpdateHandle.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.identity.updateHandle' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.identity.updateHandle"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } } export class ComAtprotoLabelNS { - _server: Server + _server: Server; constructor(server: Server) { - this._server = server + this._server = server; } queryLabels( @@ -488,8 +488,8 @@ export class ComAtprotoLabelNS { ComAtprotoLabelQueryLabels.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.label.queryLabels' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.label.queryLabels"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } subscribeLabels( @@ -499,24 +499,24 @@ export class ComAtprotoLabelNS { ComAtprotoLabelSubscribeLabels.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.label.subscribeLabels' // @ts-ignore - return this._server.xrpc.streamMethod(nsid, cfg) + const nsid = "com.atproto.label.subscribeLabels"; // @ts-ignore + return this._server.xrpc.streamMethod(nsid, cfg); } } export class ComAtprotoLexiconNS { - _server: Server + _server: Server; constructor(server: Server) { - this._server = server + this._server = server; } } export class ComAtprotoModerationNS { - _server: Server + _server: Server; constructor(server: Server) { - this._server = server + this._server = server; } createReport( @@ -526,16 +526,16 @@ export class ComAtprotoModerationNS { ComAtprotoModerationCreateReport.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.moderation.createReport' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.moderation.createReport"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } } export class ComAtprotoRepoNS { - _server: Server + _server: Server; constructor(server: Server) { - this._server = server + this._server = server; } applyWrites( @@ -545,8 +545,8 @@ export class ComAtprotoRepoNS { ComAtprotoRepoApplyWrites.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.repo.applyWrites' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.repo.applyWrites"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } createRecord( @@ -556,8 +556,8 @@ export class ComAtprotoRepoNS { ComAtprotoRepoCreateRecord.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.repo.createRecord' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.repo.createRecord"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } deleteRecord( @@ -567,8 +567,8 @@ export class ComAtprotoRepoNS { ComAtprotoRepoDeleteRecord.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.repo.deleteRecord' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.repo.deleteRecord"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } describeRepo( @@ -578,8 +578,8 @@ export class ComAtprotoRepoNS { ComAtprotoRepoDescribeRepo.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.repo.describeRepo' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.repo.describeRepo"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } getRecord( @@ -589,8 +589,8 @@ export class ComAtprotoRepoNS { ComAtprotoRepoGetRecord.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.repo.getRecord' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.repo.getRecord"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } importRepo( @@ -600,8 +600,8 @@ export class ComAtprotoRepoNS { ComAtprotoRepoImportRepo.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.repo.importRepo' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.repo.importRepo"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } listMissingBlobs( @@ -611,8 +611,8 @@ export class ComAtprotoRepoNS { ComAtprotoRepoListMissingBlobs.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.repo.listMissingBlobs' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.repo.listMissingBlobs"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } listRecords( @@ -622,8 +622,8 @@ export class ComAtprotoRepoNS { ComAtprotoRepoListRecords.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.repo.listRecords' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.repo.listRecords"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } putRecord( @@ -633,8 +633,8 @@ export class ComAtprotoRepoNS { ComAtprotoRepoPutRecord.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.repo.putRecord' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.repo.putRecord"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } uploadBlob( @@ -644,16 +644,16 @@ export class ComAtprotoRepoNS { ComAtprotoRepoUploadBlob.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.repo.uploadBlob' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.repo.uploadBlob"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } } export class ComAtprotoServerNS { - _server: Server + _server: Server; constructor(server: Server) { - this._server = server + this._server = server; } activateAccount( @@ -663,8 +663,8 @@ export class ComAtprotoServerNS { ComAtprotoServerActivateAccount.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.server.activateAccount' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.server.activateAccount"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } checkAccountStatus( @@ -674,8 +674,8 @@ export class ComAtprotoServerNS { ComAtprotoServerCheckAccountStatus.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.server.checkAccountStatus' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.server.checkAccountStatus"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } confirmEmail( @@ -685,8 +685,8 @@ export class ComAtprotoServerNS { ComAtprotoServerConfirmEmail.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.server.confirmEmail' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.server.confirmEmail"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } createAccount( @@ -696,8 +696,8 @@ export class ComAtprotoServerNS { ComAtprotoServerCreateAccount.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.server.createAccount' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.server.createAccount"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } createAppPassword( @@ -707,8 +707,8 @@ export class ComAtprotoServerNS { ComAtprotoServerCreateAppPassword.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.server.createAppPassword' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.server.createAppPassword"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } createInviteCode( @@ -718,8 +718,8 @@ export class ComAtprotoServerNS { ComAtprotoServerCreateInviteCode.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.server.createInviteCode' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.server.createInviteCode"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } createInviteCodes( @@ -729,8 +729,8 @@ export class ComAtprotoServerNS { ComAtprotoServerCreateInviteCodes.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.server.createInviteCodes' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.server.createInviteCodes"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } createSession( @@ -740,8 +740,8 @@ export class ComAtprotoServerNS { ComAtprotoServerCreateSession.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.server.createSession' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.server.createSession"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } deactivateAccount( @@ -751,8 +751,8 @@ export class ComAtprotoServerNS { ComAtprotoServerDeactivateAccount.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.server.deactivateAccount' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.server.deactivateAccount"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } deleteAccount( @@ -762,8 +762,8 @@ export class ComAtprotoServerNS { ComAtprotoServerDeleteAccount.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.server.deleteAccount' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.server.deleteAccount"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } deleteSession( @@ -773,8 +773,8 @@ export class ComAtprotoServerNS { ComAtprotoServerDeleteSession.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.server.deleteSession' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.server.deleteSession"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } describeServer( @@ -784,8 +784,8 @@ export class ComAtprotoServerNS { ComAtprotoServerDescribeServer.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.server.describeServer' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.server.describeServer"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } getAccountInviteCodes( @@ -795,8 +795,8 @@ export class ComAtprotoServerNS { ComAtprotoServerGetAccountInviteCodes.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.server.getAccountInviteCodes' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.server.getAccountInviteCodes"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } getServiceAuth( @@ -806,8 +806,8 @@ export class ComAtprotoServerNS { ComAtprotoServerGetServiceAuth.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.server.getServiceAuth' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.server.getServiceAuth"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } getSession( @@ -817,8 +817,8 @@ export class ComAtprotoServerNS { ComAtprotoServerGetSession.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.server.getSession' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.server.getSession"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } listAppPasswords( @@ -828,8 +828,8 @@ export class ComAtprotoServerNS { ComAtprotoServerListAppPasswords.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.server.listAppPasswords' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.server.listAppPasswords"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } refreshSession( @@ -839,8 +839,8 @@ export class ComAtprotoServerNS { ComAtprotoServerRefreshSession.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.server.refreshSession' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.server.refreshSession"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } requestAccountDelete( @@ -850,8 +850,8 @@ export class ComAtprotoServerNS { ComAtprotoServerRequestAccountDelete.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.server.requestAccountDelete' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.server.requestAccountDelete"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } requestEmailConfirmation( @@ -861,8 +861,8 @@ export class ComAtprotoServerNS { ComAtprotoServerRequestEmailConfirmation.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.server.requestEmailConfirmation' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.server.requestEmailConfirmation"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } requestEmailUpdate( @@ -872,8 +872,8 @@ export class ComAtprotoServerNS { ComAtprotoServerRequestEmailUpdate.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.server.requestEmailUpdate' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.server.requestEmailUpdate"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } requestPasswordReset( @@ -883,8 +883,8 @@ export class ComAtprotoServerNS { ComAtprotoServerRequestPasswordReset.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.server.requestPasswordReset' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.server.requestPasswordReset"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } reserveSigningKey( @@ -894,8 +894,8 @@ export class ComAtprotoServerNS { ComAtprotoServerReserveSigningKey.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.server.reserveSigningKey' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.server.reserveSigningKey"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } resetPassword( @@ -905,8 +905,8 @@ export class ComAtprotoServerNS { ComAtprotoServerResetPassword.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.server.resetPassword' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.server.resetPassword"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } revokeAppPassword( @@ -916,8 +916,8 @@ export class ComAtprotoServerNS { ComAtprotoServerRevokeAppPassword.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.server.revokeAppPassword' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.server.revokeAppPassword"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } updateEmail( @@ -927,16 +927,16 @@ export class ComAtprotoServerNS { ComAtprotoServerUpdateEmail.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.server.updateEmail' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.server.updateEmail"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } } export class ComAtprotoSyncNS { - _server: Server + _server: Server; constructor(server: Server) { - this._server = server + this._server = server; } getBlob( @@ -946,8 +946,8 @@ export class ComAtprotoSyncNS { ComAtprotoSyncGetBlob.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.sync.getBlob' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.sync.getBlob"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } getBlocks( @@ -957,8 +957,8 @@ export class ComAtprotoSyncNS { ComAtprotoSyncGetBlocks.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.sync.getBlocks' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.sync.getBlocks"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } getCheckout( @@ -968,8 +968,8 @@ export class ComAtprotoSyncNS { ComAtprotoSyncGetCheckout.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.sync.getCheckout' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.sync.getCheckout"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } getHead( @@ -979,8 +979,8 @@ export class ComAtprotoSyncNS { ComAtprotoSyncGetHead.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.sync.getHead' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.sync.getHead"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } getLatestCommit( @@ -990,8 +990,8 @@ export class ComAtprotoSyncNS { ComAtprotoSyncGetLatestCommit.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.sync.getLatestCommit' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.sync.getLatestCommit"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } getRecord( @@ -1001,8 +1001,8 @@ export class ComAtprotoSyncNS { ComAtprotoSyncGetRecord.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.sync.getRecord' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.sync.getRecord"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } getRepo( @@ -1012,8 +1012,8 @@ export class ComAtprotoSyncNS { ComAtprotoSyncGetRepo.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.sync.getRepo' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.sync.getRepo"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } getRepoStatus( @@ -1023,8 +1023,8 @@ export class ComAtprotoSyncNS { ComAtprotoSyncGetRepoStatus.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.sync.getRepoStatus' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.sync.getRepoStatus"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } listBlobs( @@ -1034,8 +1034,8 @@ export class ComAtprotoSyncNS { ComAtprotoSyncListBlobs.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.sync.listBlobs' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.sync.listBlobs"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } listReposByCollection( @@ -1045,8 +1045,8 @@ export class ComAtprotoSyncNS { ComAtprotoSyncListReposByCollection.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.sync.listReposByCollection' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.sync.listReposByCollection"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } listRepos( @@ -1056,8 +1056,8 @@ export class ComAtprotoSyncNS { ComAtprotoSyncListRepos.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.sync.listRepos' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.sync.listRepos"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } notifyOfUpdate( @@ -1067,8 +1067,8 @@ export class ComAtprotoSyncNS { ComAtprotoSyncNotifyOfUpdate.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.sync.notifyOfUpdate' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.sync.notifyOfUpdate"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } requestCrawl( @@ -1078,8 +1078,8 @@ export class ComAtprotoSyncNS { ComAtprotoSyncRequestCrawl.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.sync.requestCrawl' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.sync.requestCrawl"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } subscribeRepos( @@ -1089,16 +1089,16 @@ export class ComAtprotoSyncNS { ComAtprotoSyncSubscribeRepos.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.sync.subscribeRepos' // @ts-ignore - return this._server.xrpc.streamMethod(nsid, cfg) + const nsid = "com.atproto.sync.subscribeRepos"; // @ts-ignore + return this._server.xrpc.streamMethod(nsid, cfg); } } export class ComAtprotoTempNS { - _server: Server + _server: Server; constructor(server: Server) { - this._server = server + this._server = server; } addReservedHandle( @@ -1108,8 +1108,8 @@ export class ComAtprotoTempNS { ComAtprotoTempAddReservedHandle.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.temp.addReservedHandle' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.temp.addReservedHandle"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } checkSignupQueue( @@ -1119,8 +1119,8 @@ export class ComAtprotoTempNS { ComAtprotoTempCheckSignupQueue.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.temp.checkSignupQueue' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.temp.checkSignupQueue"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } fetchLabels( @@ -1130,8 +1130,8 @@ export class ComAtprotoTempNS { ComAtprotoTempFetchLabels.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.temp.fetchLabels' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.temp.fetchLabels"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } requestPhoneVerification( @@ -1141,52 +1141,52 @@ export class ComAtprotoTempNS { ComAtprotoTempRequestPhoneVerification.HandlerReqCtx> >, ) { - const nsid = 'com.atproto.temp.requestPhoneVerification' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "com.atproto.temp.requestPhoneVerification"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } } export class SoNS { - _server: Server - sprk: SoSprkNS + _server: Server; + sprk: SoSprkNS; constructor(server: Server) { - this._server = server - this.sprk = new SoSprkNS(server) + this._server = server; + this.sprk = new SoSprkNS(server); } } export class SoSprkNS { - _server: Server - actor: SoSprkActorNS - embed: SoSprkEmbedNS - feed: SoSprkFeedNS - graph: SoSprkGraphNS - labeler: SoSprkLabelerNS - notification: SoSprkNotificationNS - richtext: SoSprkRichtextNS - unspecced: SoSprkUnspeccedNS - video: SoSprkVideoNS + _server: Server; + actor: SoSprkActorNS; + embed: SoSprkEmbedNS; + feed: SoSprkFeedNS; + graph: SoSprkGraphNS; + labeler: SoSprkLabelerNS; + notification: SoSprkNotificationNS; + richtext: SoSprkRichtextNS; + unspecced: SoSprkUnspeccedNS; + video: SoSprkVideoNS; constructor(server: Server) { - this._server = server - this.actor = new SoSprkActorNS(server) - this.embed = new SoSprkEmbedNS(server) - this.feed = new SoSprkFeedNS(server) - this.graph = new SoSprkGraphNS(server) - this.labeler = new SoSprkLabelerNS(server) - this.notification = new SoSprkNotificationNS(server) - this.richtext = new SoSprkRichtextNS(server) - this.unspecced = new SoSprkUnspeccedNS(server) - this.video = new SoSprkVideoNS(server) + this._server = server; + this.actor = new SoSprkActorNS(server); + this.embed = new SoSprkEmbedNS(server); + this.feed = new SoSprkFeedNS(server); + this.graph = new SoSprkGraphNS(server); + this.labeler = new SoSprkLabelerNS(server); + this.notification = new SoSprkNotificationNS(server); + this.richtext = new SoSprkRichtextNS(server); + this.unspecced = new SoSprkUnspeccedNS(server); + this.video = new SoSprkVideoNS(server); } } export class SoSprkActorNS { - _server: Server + _server: Server; constructor(server: Server) { - this._server = server + this._server = server; } getPreferences( @@ -1196,8 +1196,8 @@ export class SoSprkActorNS { SoSprkActorGetPreferences.HandlerReqCtx> >, ) { - const nsid = 'so.sprk.actor.getPreferences' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "so.sprk.actor.getPreferences"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } getProfile( @@ -1207,8 +1207,8 @@ export class SoSprkActorNS { SoSprkActorGetProfile.HandlerReqCtx> >, ) { - const nsid = 'so.sprk.actor.getProfile' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "so.sprk.actor.getProfile"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } getProfiles( @@ -1218,8 +1218,8 @@ export class SoSprkActorNS { SoSprkActorGetProfiles.HandlerReqCtx> >, ) { - const nsid = 'so.sprk.actor.getProfiles' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "so.sprk.actor.getProfiles"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } getSuggestions( @@ -1229,8 +1229,8 @@ export class SoSprkActorNS { SoSprkActorGetSuggestions.HandlerReqCtx> >, ) { - const nsid = 'so.sprk.actor.getSuggestions' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "so.sprk.actor.getSuggestions"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } putPreferences( @@ -1240,8 +1240,8 @@ export class SoSprkActorNS { SoSprkActorPutPreferences.HandlerReqCtx> >, ) { - const nsid = 'so.sprk.actor.putPreferences' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "so.sprk.actor.putPreferences"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } searchActors( @@ -1251,8 +1251,8 @@ export class SoSprkActorNS { SoSprkActorSearchActors.HandlerReqCtx> >, ) { - const nsid = 'so.sprk.actor.searchActors' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "so.sprk.actor.searchActors"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } searchActorsTypeahead( @@ -1262,24 +1262,24 @@ export class SoSprkActorNS { SoSprkActorSearchActorsTypeahead.HandlerReqCtx> >, ) { - const nsid = 'so.sprk.actor.searchActorsTypeahead' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "so.sprk.actor.searchActorsTypeahead"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } } export class SoSprkEmbedNS { - _server: Server + _server: Server; constructor(server: Server) { - this._server = server + this._server = server; } } export class SoSprkFeedNS { - _server: Server + _server: Server; constructor(server: Server) { - this._server = server + this._server = server; } describeFeedGenerator( @@ -1289,8 +1289,8 @@ export class SoSprkFeedNS { SoSprkFeedDescribeFeedGenerator.HandlerReqCtx> >, ) { - const nsid = 'so.sprk.feed.describeFeedGenerator' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "so.sprk.feed.describeFeedGenerator"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } getActorFeeds( @@ -1300,8 +1300,8 @@ export class SoSprkFeedNS { SoSprkFeedGetActorFeeds.HandlerReqCtx> >, ) { - const nsid = 'so.sprk.feed.getActorFeeds' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "so.sprk.feed.getActorFeeds"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } getActorLikes( @@ -1311,8 +1311,8 @@ export class SoSprkFeedNS { SoSprkFeedGetActorLikes.HandlerReqCtx> >, ) { - const nsid = 'so.sprk.feed.getActorLikes' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "so.sprk.feed.getActorLikes"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } getActorLooks( @@ -1322,8 +1322,8 @@ export class SoSprkFeedNS { SoSprkFeedGetActorLooks.HandlerReqCtx> >, ) { - const nsid = 'so.sprk.feed.getActorLooks' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "so.sprk.feed.getActorLooks"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } getAuthorFeed( @@ -1333,8 +1333,8 @@ export class SoSprkFeedNS { SoSprkFeedGetAuthorFeed.HandlerReqCtx> >, ) { - const nsid = 'so.sprk.feed.getAuthorFeed' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "so.sprk.feed.getAuthorFeed"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } getFeedGenerator( @@ -1344,8 +1344,8 @@ export class SoSprkFeedNS { SoSprkFeedGetFeedGenerator.HandlerReqCtx> >, ) { - const nsid = 'so.sprk.feed.getFeedGenerator' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "so.sprk.feed.getFeedGenerator"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } getFeedGenerators( @@ -1355,8 +1355,8 @@ export class SoSprkFeedNS { SoSprkFeedGetFeedGenerators.HandlerReqCtx> >, ) { - const nsid = 'so.sprk.feed.getFeedGenerators' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "so.sprk.feed.getFeedGenerators"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } getFeed( @@ -1366,8 +1366,8 @@ export class SoSprkFeedNS { SoSprkFeedGetFeed.HandlerReqCtx> >, ) { - const nsid = 'so.sprk.feed.getFeed' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "so.sprk.feed.getFeed"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } getFeedSkeleton( @@ -1377,8 +1377,8 @@ export class SoSprkFeedNS { SoSprkFeedGetFeedSkeleton.HandlerReqCtx> >, ) { - const nsid = 'so.sprk.feed.getFeedSkeleton' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "so.sprk.feed.getFeedSkeleton"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } getLikes( @@ -1388,8 +1388,8 @@ export class SoSprkFeedNS { SoSprkFeedGetLikes.HandlerReqCtx> >, ) { - const nsid = 'so.sprk.feed.getLikes' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "so.sprk.feed.getLikes"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } getListFeed( @@ -1399,8 +1399,8 @@ export class SoSprkFeedNS { SoSprkFeedGetListFeed.HandlerReqCtx> >, ) { - const nsid = 'so.sprk.feed.getListFeed' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "so.sprk.feed.getListFeed"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } getLooks( @@ -1410,8 +1410,8 @@ export class SoSprkFeedNS { SoSprkFeedGetLooks.HandlerReqCtx> >, ) { - const nsid = 'so.sprk.feed.getLooks' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "so.sprk.feed.getLooks"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } getPosts( @@ -1421,8 +1421,8 @@ export class SoSprkFeedNS { SoSprkFeedGetPosts.HandlerReqCtx> >, ) { - const nsid = 'so.sprk.feed.getPosts' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "so.sprk.feed.getPosts"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } getPostThread( @@ -1432,8 +1432,8 @@ export class SoSprkFeedNS { SoSprkFeedGetPostThread.HandlerReqCtx> >, ) { - const nsid = 'so.sprk.feed.getPostThread' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "so.sprk.feed.getPostThread"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } getQuotes( @@ -1443,8 +1443,8 @@ export class SoSprkFeedNS { SoSprkFeedGetQuotes.HandlerReqCtx> >, ) { - const nsid = 'so.sprk.feed.getQuotes' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "so.sprk.feed.getQuotes"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } getRepostedBy( @@ -1454,8 +1454,8 @@ export class SoSprkFeedNS { SoSprkFeedGetRepostedBy.HandlerReqCtx> >, ) { - const nsid = 'so.sprk.feed.getRepostedBy' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "so.sprk.feed.getRepostedBy"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } getSuggestedFeeds( @@ -1465,8 +1465,8 @@ export class SoSprkFeedNS { SoSprkFeedGetSuggestedFeeds.HandlerReqCtx> >, ) { - const nsid = 'so.sprk.feed.getSuggestedFeeds' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "so.sprk.feed.getSuggestedFeeds"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } getTimeline( @@ -1476,8 +1476,8 @@ export class SoSprkFeedNS { SoSprkFeedGetTimeline.HandlerReqCtx> >, ) { - const nsid = 'so.sprk.feed.getTimeline' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "so.sprk.feed.getTimeline"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } searchPosts( @@ -1487,8 +1487,8 @@ export class SoSprkFeedNS { SoSprkFeedSearchPosts.HandlerReqCtx> >, ) { - const nsid = 'so.sprk.feed.searchPosts' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "so.sprk.feed.searchPosts"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } sendInteractions( @@ -1498,16 +1498,16 @@ export class SoSprkFeedNS { SoSprkFeedSendInteractions.HandlerReqCtx> >, ) { - const nsid = 'so.sprk.feed.sendInteractions' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "so.sprk.feed.sendInteractions"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } } export class SoSprkGraphNS { - _server: Server + _server: Server; constructor(server: Server) { - this._server = server + this._server = server; } getActorStarterPacks( @@ -1517,8 +1517,8 @@ export class SoSprkGraphNS { SoSprkGraphGetActorStarterPacks.HandlerReqCtx> >, ) { - const nsid = 'so.sprk.graph.getActorStarterPacks' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "so.sprk.graph.getActorStarterPacks"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } getBlocks( @@ -1528,8 +1528,8 @@ export class SoSprkGraphNS { SoSprkGraphGetBlocks.HandlerReqCtx> >, ) { - const nsid = 'so.sprk.graph.getBlocks' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "so.sprk.graph.getBlocks"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } getFollowers( @@ -1539,8 +1539,8 @@ export class SoSprkGraphNS { SoSprkGraphGetFollowers.HandlerReqCtx> >, ) { - const nsid = 'so.sprk.graph.getFollowers' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "so.sprk.graph.getFollowers"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } getFollows( @@ -1550,8 +1550,8 @@ export class SoSprkGraphNS { SoSprkGraphGetFollows.HandlerReqCtx> >, ) { - const nsid = 'so.sprk.graph.getFollows' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "so.sprk.graph.getFollows"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } getKnownFollowers( @@ -1561,8 +1561,8 @@ export class SoSprkGraphNS { SoSprkGraphGetKnownFollowers.HandlerReqCtx> >, ) { - const nsid = 'so.sprk.graph.getKnownFollowers' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "so.sprk.graph.getKnownFollowers"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } getListBlocks( @@ -1572,8 +1572,8 @@ export class SoSprkGraphNS { SoSprkGraphGetListBlocks.HandlerReqCtx> >, ) { - const nsid = 'so.sprk.graph.getListBlocks' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "so.sprk.graph.getListBlocks"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } getList( @@ -1583,8 +1583,8 @@ export class SoSprkGraphNS { SoSprkGraphGetList.HandlerReqCtx> >, ) { - const nsid = 'so.sprk.graph.getList' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "so.sprk.graph.getList"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } getListMutes( @@ -1594,8 +1594,8 @@ export class SoSprkGraphNS { SoSprkGraphGetListMutes.HandlerReqCtx> >, ) { - const nsid = 'so.sprk.graph.getListMutes' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "so.sprk.graph.getListMutes"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } getLists( @@ -1605,8 +1605,8 @@ export class SoSprkGraphNS { SoSprkGraphGetLists.HandlerReqCtx> >, ) { - const nsid = 'so.sprk.graph.getLists' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "so.sprk.graph.getLists"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } getMutes( @@ -1616,8 +1616,8 @@ export class SoSprkGraphNS { SoSprkGraphGetMutes.HandlerReqCtx> >, ) { - const nsid = 'so.sprk.graph.getMutes' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "so.sprk.graph.getMutes"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } getRelationships( @@ -1627,8 +1627,8 @@ export class SoSprkGraphNS { SoSprkGraphGetRelationships.HandlerReqCtx> >, ) { - const nsid = 'so.sprk.graph.getRelationships' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "so.sprk.graph.getRelationships"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } getStarterPack( @@ -1638,8 +1638,8 @@ export class SoSprkGraphNS { SoSprkGraphGetStarterPack.HandlerReqCtx> >, ) { - const nsid = 'so.sprk.graph.getStarterPack' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "so.sprk.graph.getStarterPack"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } getStarterPacks( @@ -1649,8 +1649,8 @@ export class SoSprkGraphNS { SoSprkGraphGetStarterPacks.HandlerReqCtx> >, ) { - const nsid = 'so.sprk.graph.getStarterPacks' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "so.sprk.graph.getStarterPacks"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } getSuggestedFollowsByActor( @@ -1660,8 +1660,8 @@ export class SoSprkGraphNS { SoSprkGraphGetSuggestedFollowsByActor.HandlerReqCtx> >, ) { - const nsid = 'so.sprk.graph.getSuggestedFollowsByActor' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "so.sprk.graph.getSuggestedFollowsByActor"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } muteActor( @@ -1671,8 +1671,8 @@ export class SoSprkGraphNS { SoSprkGraphMuteActor.HandlerReqCtx> >, ) { - const nsid = 'so.sprk.graph.muteActor' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "so.sprk.graph.muteActor"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } muteActorList( @@ -1682,8 +1682,8 @@ export class SoSprkGraphNS { SoSprkGraphMuteActorList.HandlerReqCtx> >, ) { - const nsid = 'so.sprk.graph.muteActorList' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "so.sprk.graph.muteActorList"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } muteThread( @@ -1693,8 +1693,8 @@ export class SoSprkGraphNS { SoSprkGraphMuteThread.HandlerReqCtx> >, ) { - const nsid = 'so.sprk.graph.muteThread' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "so.sprk.graph.muteThread"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } searchStarterPacks( @@ -1704,8 +1704,8 @@ export class SoSprkGraphNS { SoSprkGraphSearchStarterPacks.HandlerReqCtx> >, ) { - const nsid = 'so.sprk.graph.searchStarterPacks' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "so.sprk.graph.searchStarterPacks"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } unmuteActor( @@ -1715,8 +1715,8 @@ export class SoSprkGraphNS { SoSprkGraphUnmuteActor.HandlerReqCtx> >, ) { - const nsid = 'so.sprk.graph.unmuteActor' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "so.sprk.graph.unmuteActor"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } unmuteActorList( @@ -1726,8 +1726,8 @@ export class SoSprkGraphNS { SoSprkGraphUnmuteActorList.HandlerReqCtx> >, ) { - const nsid = 'so.sprk.graph.unmuteActorList' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "so.sprk.graph.unmuteActorList"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } unmuteThread( @@ -1737,16 +1737,16 @@ export class SoSprkGraphNS { SoSprkGraphUnmuteThread.HandlerReqCtx> >, ) { - const nsid = 'so.sprk.graph.unmuteThread' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "so.sprk.graph.unmuteThread"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } } export class SoSprkLabelerNS { - _server: Server + _server: Server; constructor(server: Server) { - this._server = server + this._server = server; } getServices( @@ -1756,16 +1756,16 @@ export class SoSprkLabelerNS { SoSprkLabelerGetServices.HandlerReqCtx> >, ) { - const nsid = 'so.sprk.labeler.getServices' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "so.sprk.labeler.getServices"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } } export class SoSprkNotificationNS { - _server: Server + _server: Server; constructor(server: Server) { - this._server = server + this._server = server; } getUnreadCount( @@ -1775,8 +1775,8 @@ export class SoSprkNotificationNS { SoSprkNotificationGetUnreadCount.HandlerReqCtx> >, ) { - const nsid = 'so.sprk.notification.getUnreadCount' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "so.sprk.notification.getUnreadCount"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } listNotifications( @@ -1786,8 +1786,8 @@ export class SoSprkNotificationNS { SoSprkNotificationListNotifications.HandlerReqCtx> >, ) { - const nsid = 'so.sprk.notification.listNotifications' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "so.sprk.notification.listNotifications"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } putPreferences( @@ -1797,8 +1797,8 @@ export class SoSprkNotificationNS { SoSprkNotificationPutPreferences.HandlerReqCtx> >, ) { - const nsid = 'so.sprk.notification.putPreferences' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "so.sprk.notification.putPreferences"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } registerPush( @@ -1808,8 +1808,8 @@ export class SoSprkNotificationNS { SoSprkNotificationRegisterPush.HandlerReqCtx> >, ) { - const nsid = 'so.sprk.notification.registerPush' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "so.sprk.notification.registerPush"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } updateSeen( @@ -1819,24 +1819,24 @@ export class SoSprkNotificationNS { SoSprkNotificationUpdateSeen.HandlerReqCtx> >, ) { - const nsid = 'so.sprk.notification.updateSeen' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "so.sprk.notification.updateSeen"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } } export class SoSprkRichtextNS { - _server: Server + _server: Server; constructor(server: Server) { - this._server = server + this._server = server; } } export class SoSprkUnspeccedNS { - _server: Server + _server: Server; constructor(server: Server) { - this._server = server + this._server = server; } getConfig( @@ -1846,8 +1846,8 @@ export class SoSprkUnspeccedNS { SoSprkUnspeccedGetConfig.HandlerReqCtx> >, ) { - const nsid = 'so.sprk.unspecced.getConfig' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "so.sprk.unspecced.getConfig"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } getPopularFeedGenerators( @@ -1857,8 +1857,8 @@ export class SoSprkUnspeccedNS { SoSprkUnspeccedGetPopularFeedGenerators.HandlerReqCtx> >, ) { - const nsid = 'so.sprk.unspecced.getPopularFeedGenerators' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "so.sprk.unspecced.getPopularFeedGenerators"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } getSuggestionsSkeleton( @@ -1868,8 +1868,8 @@ export class SoSprkUnspeccedNS { SoSprkUnspeccedGetSuggestionsSkeleton.HandlerReqCtx> >, ) { - const nsid = 'so.sprk.unspecced.getSuggestionsSkeleton' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "so.sprk.unspecced.getSuggestionsSkeleton"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } getTaggedSuggestions( @@ -1879,8 +1879,8 @@ export class SoSprkUnspeccedNS { SoSprkUnspeccedGetTaggedSuggestions.HandlerReqCtx> >, ) { - const nsid = 'so.sprk.unspecced.getTaggedSuggestions' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "so.sprk.unspecced.getTaggedSuggestions"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } getTrendingTopics( @@ -1890,8 +1890,8 @@ export class SoSprkUnspeccedNS { SoSprkUnspeccedGetTrendingTopics.HandlerReqCtx> >, ) { - const nsid = 'so.sprk.unspecced.getTrendingTopics' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "so.sprk.unspecced.getTrendingTopics"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } searchActorsSkeleton( @@ -1901,8 +1901,8 @@ export class SoSprkUnspeccedNS { SoSprkUnspeccedSearchActorsSkeleton.HandlerReqCtx> >, ) { - const nsid = 'so.sprk.unspecced.searchActorsSkeleton' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "so.sprk.unspecced.searchActorsSkeleton"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } searchPostsSkeleton( @@ -1912,8 +1912,8 @@ export class SoSprkUnspeccedNS { SoSprkUnspeccedSearchPostsSkeleton.HandlerReqCtx> >, ) { - const nsid = 'so.sprk.unspecced.searchPostsSkeleton' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "so.sprk.unspecced.searchPostsSkeleton"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } searchStarterPacksSkeleton( @@ -1923,16 +1923,16 @@ export class SoSprkUnspeccedNS { SoSprkUnspeccedSearchStarterPacksSkeleton.HandlerReqCtx> >, ) { - const nsid = 'so.sprk.unspecced.searchStarterPacksSkeleton' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "so.sprk.unspecced.searchStarterPacksSkeleton"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } } export class SoSprkVideoNS { - _server: Server + _server: Server; constructor(server: Server) { - this._server = server + this._server = server; } getJobStatus( @@ -1942,8 +1942,8 @@ export class SoSprkVideoNS { SoSprkVideoGetJobStatus.HandlerReqCtx> >, ) { - const nsid = 'so.sprk.video.getJobStatus' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "so.sprk.video.getJobStatus"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } getUploadLimits( @@ -1953,8 +1953,8 @@ export class SoSprkVideoNS { SoSprkVideoGetUploadLimits.HandlerReqCtx> >, ) { - const nsid = 'so.sprk.video.getUploadLimits' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "so.sprk.video.getUploadLimits"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } uploadVideo( @@ -1964,33 +1964,33 @@ export class SoSprkVideoNS { SoSprkVideoUploadVideo.HandlerReqCtx> >, ) { - const nsid = 'so.sprk.video.uploadVideo' // @ts-ignore - return this._server.xrpc.method(nsid, cfg) + const nsid = "so.sprk.video.uploadVideo"; // @ts-ignore + return this._server.xrpc.method(nsid, cfg); } } type SharedRateLimitOpts = { - name: string - calcKey?: (ctx: T) => string | null - calcPoints?: (ctx: T) => number -} + name: string; + calcKey?: (ctx: T) => string | null; + calcPoints?: (ctx: T) => number; +}; type RouteRateLimitOpts = { - durationMs: number - points: number - calcKey?: (ctx: T) => string | null - calcPoints?: (ctx: T) => number -} -type HandlerOpts = { blobLimit?: number } -type HandlerRateLimitOpts = SharedRateLimitOpts | RouteRateLimitOpts + durationMs: number; + points: number; + calcKey?: (ctx: T) => string | null; + calcPoints?: (ctx: T) => number; +}; +type HandlerOpts = { blobLimit?: number }; +type HandlerRateLimitOpts = SharedRateLimitOpts | RouteRateLimitOpts; type ConfigOf = | Handler | { - auth?: Auth - opts?: HandlerOpts - rateLimit?: HandlerRateLimitOpts | HandlerRateLimitOpts[] - handler: Handler - } + auth?: Auth; + opts?: HandlerOpts; + rateLimit?: HandlerRateLimitOpts | HandlerRateLimitOpts[]; + handler: Handler; + }; type ExtractAuth = Extract< Awaited>, { credentials: unknown } -> +>; diff --git a/services/appview/lexicon/lexicons.ts b/services/appview/lexicon/lexicons.ts new file mode 100644 index 0000000..b0a859a --- /dev/null +++ b/services/appview/lexicon/lexicons.ts @@ -0,0 +1,10162 @@ +/** + * GENERATED CODE - DO NOT MODIFY + */ +import { + LexiconDoc, + Lexicons, + ValidationError, + ValidationResult, +} from "@atproto/lexicon"; +import { $Typed, is$typed, maybe$typed } from "./util.ts"; + +export const schemaDict = { + ComAtprotoAdminDefs: { + lexicon: 1, + id: "com.atproto.admin.defs", + defs: { + statusAttr: { + type: "object", + required: ["applied"], + properties: { + applied: { + type: "boolean", + }, + ref: { + type: "string", + }, + }, + }, + accountView: { + type: "object", + required: ["did", "handle", "indexedAt"], + properties: { + did: { + type: "string", + format: "did", + }, + handle: { + type: "string", + format: "handle", + }, + email: { + type: "string", + }, + relatedRecords: { + type: "array", + items: { + type: "unknown", + }, + }, + indexedAt: { + type: "string", + format: "datetime", + }, + invitedBy: { + type: "ref", + ref: "lex:com.atproto.server.defs#inviteCode", + }, + invites: { + type: "array", + items: { + type: "ref", + ref: "lex:com.atproto.server.defs#inviteCode", + }, + }, + invitesDisabled: { + type: "boolean", + }, + emailConfirmedAt: { + type: "string", + format: "datetime", + }, + inviteNote: { + type: "string", + }, + deactivatedAt: { + type: "string", + format: "datetime", + }, + threatSignatures: { + type: "array", + items: { + type: "ref", + ref: "lex:com.atproto.admin.defs#threatSignature", + }, + }, + }, + }, + repoRef: { + type: "object", + required: ["did"], + properties: { + did: { + type: "string", + format: "did", + }, + }, + }, + repoBlobRef: { + type: "object", + required: ["did", "cid"], + properties: { + did: { + type: "string", + format: "did", + }, + cid: { + type: "string", + format: "cid", + }, + recordUri: { + type: "string", + format: "at-uri", + }, + }, + }, + threatSignature: { + type: "object", + required: ["property", "value"], + properties: { + property: { + type: "string", + }, + value: { + type: "string", + }, + }, + }, + }, + }, + ComAtprotoAdminDeleteAccount: { + lexicon: 1, + id: "com.atproto.admin.deleteAccount", + defs: { + main: { + type: "procedure", + description: "Delete a user account as an administrator.", + input: { + encoding: "application/json", + schema: { + type: "object", + required: ["did"], + properties: { + did: { + type: "string", + format: "did", + }, + }, + }, + }, + }, + }, + }, + ComAtprotoAdminDisableAccountInvites: { + lexicon: 1, + id: "com.atproto.admin.disableAccountInvites", + defs: { + main: { + type: "procedure", + description: + "Disable an account from receiving new invite codes, but does not invalidate existing codes.", + input: { + encoding: "application/json", + schema: { + type: "object", + required: ["account"], + properties: { + account: { + type: "string", + format: "did", + }, + note: { + type: "string", + description: "Optional reason for disabled invites.", + }, + }, + }, + }, + }, + }, + }, + ComAtprotoAdminDisableInviteCodes: { + lexicon: 1, + id: "com.atproto.admin.disableInviteCodes", + defs: { + main: { + type: "procedure", + description: + "Disable some set of codes and/or all codes associated with a set of users.", + input: { + encoding: "application/json", + schema: { + type: "object", + properties: { + codes: { + type: "array", + items: { + type: "string", + }, + }, + accounts: { + type: "array", + items: { + type: "string", + }, + }, + }, + }, + }, + }, + }, + }, + ComAtprotoAdminEnableAccountInvites: { + lexicon: 1, + id: "com.atproto.admin.enableAccountInvites", + defs: { + main: { + type: "procedure", + description: "Re-enable an account's ability to receive invite codes.", + input: { + encoding: "application/json", + schema: { + type: "object", + required: ["account"], + properties: { + account: { + type: "string", + format: "did", + }, + note: { + type: "string", + description: "Optional reason for enabled invites.", + }, + }, + }, + }, + }, + }, + }, + ComAtprotoAdminGetAccountInfo: { + lexicon: 1, + id: "com.atproto.admin.getAccountInfo", + defs: { + main: { + type: "query", + description: "Get details about an account.", + parameters: { + type: "params", + required: ["did"], + properties: { + did: { + type: "string", + format: "did", + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "ref", + ref: "lex:com.atproto.admin.defs#accountView", + }, + }, + }, + }, + }, + ComAtprotoAdminGetAccountInfos: { + lexicon: 1, + id: "com.atproto.admin.getAccountInfos", + defs: { + main: { + type: "query", + description: "Get details about some accounts.", + parameters: { + type: "params", + required: ["dids"], + properties: { + dids: { + type: "array", + items: { + type: "string", + format: "did", + }, + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["infos"], + properties: { + infos: { + type: "array", + items: { + type: "ref", + ref: "lex:com.atproto.admin.defs#accountView", + }, + }, + }, + }, + }, + }, + }, + }, + ComAtprotoAdminGetInviteCodes: { + lexicon: 1, + id: "com.atproto.admin.getInviteCodes", + defs: { + main: { + type: "query", + description: "Get an admin view of invite codes.", + parameters: { + type: "params", + properties: { + sort: { + type: "string", + knownValues: ["recent", "usage"], + default: "recent", + }, + limit: { + type: "integer", + minimum: 1, + maximum: 500, + default: 100, + }, + cursor: { + type: "string", + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["codes"], + properties: { + cursor: { + type: "string", + }, + codes: { + type: "array", + items: { + type: "ref", + ref: "lex:com.atproto.server.defs#inviteCode", + }, + }, + }, + }, + }, + }, + }, + }, + ComAtprotoAdminGetSubjectStatus: { + lexicon: 1, + id: "com.atproto.admin.getSubjectStatus", + defs: { + main: { + type: "query", + description: + "Get the service-specific admin status of a subject (account, record, or blob).", + parameters: { + type: "params", + properties: { + did: { + type: "string", + format: "did", + }, + uri: { + type: "string", + format: "at-uri", + }, + blob: { + type: "string", + format: "cid", + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["subject"], + properties: { + subject: { + type: "union", + refs: [ + "lex:com.atproto.admin.defs#repoRef", + "lex:com.atproto.repo.strongRef", + "lex:com.atproto.admin.defs#repoBlobRef", + ], + }, + takedown: { + type: "ref", + ref: "lex:com.atproto.admin.defs#statusAttr", + }, + deactivated: { + type: "ref", + ref: "lex:com.atproto.admin.defs#statusAttr", + }, + }, + }, + }, + }, + }, + }, + ComAtprotoAdminSearchAccounts: { + lexicon: 1, + id: "com.atproto.admin.searchAccounts", + defs: { + main: { + type: "query", + description: "Get list of accounts that matches your search query.", + parameters: { + type: "params", + properties: { + email: { + type: "string", + }, + cursor: { + type: "string", + }, + limit: { + type: "integer", + minimum: 1, + maximum: 100, + default: 50, + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["accounts"], + properties: { + cursor: { + type: "string", + }, + accounts: { + type: "array", + items: { + type: "ref", + ref: "lex:com.atproto.admin.defs#accountView", + }, + }, + }, + }, + }, + }, + }, + }, + ComAtprotoAdminSendEmail: { + lexicon: 1, + id: "com.atproto.admin.sendEmail", + defs: { + main: { + type: "procedure", + description: "Send email to a user's account email address.", + input: { + encoding: "application/json", + schema: { + type: "object", + required: ["recipientDid", "content", "senderDid"], + properties: { + recipientDid: { + type: "string", + format: "did", + }, + content: { + type: "string", + }, + subject: { + type: "string", + }, + senderDid: { + type: "string", + format: "did", + }, + comment: { + type: "string", + description: + "Additional comment by the sender that won't be used in the email itself but helpful to provide more context for moderators/reviewers", + }, + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["sent"], + properties: { + sent: { + type: "boolean", + }, + }, + }, + }, + }, + }, + }, + ComAtprotoAdminUpdateAccountEmail: { + lexicon: 1, + id: "com.atproto.admin.updateAccountEmail", + defs: { + main: { + type: "procedure", + description: "Administrative action to update an account's email.", + input: { + encoding: "application/json", + schema: { + type: "object", + required: ["account", "email"], + properties: { + account: { + type: "string", + format: "at-identifier", + description: "The handle or DID of the repo.", + }, + email: { + type: "string", + }, + }, + }, + }, + }, + }, + }, + ComAtprotoAdminUpdateAccountHandle: { + lexicon: 1, + id: "com.atproto.admin.updateAccountHandle", + defs: { + main: { + type: "procedure", + description: "Administrative action to update an account's handle.", + input: { + encoding: "application/json", + schema: { + type: "object", + required: ["did", "handle"], + properties: { + did: { + type: "string", + format: "did", + }, + handle: { + type: "string", + format: "handle", + }, + }, + }, + }, + }, + }, + }, + ComAtprotoAdminUpdateAccountPassword: { + lexicon: 1, + id: "com.atproto.admin.updateAccountPassword", + defs: { + main: { + type: "procedure", + description: + "Update the password for a user account as an administrator.", + input: { + encoding: "application/json", + schema: { + type: "object", + required: ["did", "password"], + properties: { + did: { + type: "string", + format: "did", + }, + password: { + type: "string", + }, + }, + }, + }, + }, + }, + }, + ComAtprotoAdminUpdateSubjectStatus: { + lexicon: 1, + id: "com.atproto.admin.updateSubjectStatus", + defs: { + main: { + type: "procedure", + description: + "Update the service-specific admin status of a subject (account, record, or blob).", + input: { + encoding: "application/json", + schema: { + type: "object", + required: ["subject"], + properties: { + subject: { + type: "union", + refs: [ + "lex:com.atproto.admin.defs#repoRef", + "lex:com.atproto.repo.strongRef", + "lex:com.atproto.admin.defs#repoBlobRef", + ], + }, + takedown: { + type: "ref", + ref: "lex:com.atproto.admin.defs#statusAttr", + }, + deactivated: { + type: "ref", + ref: "lex:com.atproto.admin.defs#statusAttr", + }, + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["subject"], + properties: { + subject: { + type: "union", + refs: [ + "lex:com.atproto.admin.defs#repoRef", + "lex:com.atproto.repo.strongRef", + "lex:com.atproto.admin.defs#repoBlobRef", + ], + }, + takedown: { + type: "ref", + ref: "lex:com.atproto.admin.defs#statusAttr", + }, + }, + }, + }, + }, + }, + }, + ComAtprotoIdentityGetRecommendedDidCredentials: { + lexicon: 1, + id: "com.atproto.identity.getRecommendedDidCredentials", + defs: { + main: { + type: "query", + description: + "Describe the credentials that should be included in the DID doc of an account that is migrating to this service.", + output: { + encoding: "application/json", + schema: { + type: "object", + properties: { + rotationKeys: { + description: + "Recommended rotation keys for PLC dids. Should be undefined (or ignored) for did:webs.", + type: "array", + items: { + type: "string", + }, + }, + alsoKnownAs: { + type: "array", + items: { + type: "string", + }, + }, + verificationMethods: { + type: "unknown", + }, + services: { + type: "unknown", + }, + }, + }, + }, + }, + }, + }, + ComAtprotoIdentityRequestPlcOperationSignature: { + lexicon: 1, + id: "com.atproto.identity.requestPlcOperationSignature", + defs: { + main: { + type: "procedure", + description: + "Request an email with a code to in order to request a signed PLC operation. Requires Auth.", + }, + }, + }, + ComAtprotoIdentityResolveHandle: { + lexicon: 1, + id: "com.atproto.identity.resolveHandle", + defs: { + main: { + type: "query", + description: "Resolves a handle (domain name) to a DID.", + parameters: { + type: "params", + required: ["handle"], + properties: { + handle: { + type: "string", + format: "handle", + description: "The handle to resolve.", + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["did"], + properties: { + did: { + type: "string", + format: "did", + }, + }, + }, + }, + }, + }, + }, + ComAtprotoIdentitySignPlcOperation: { + lexicon: 1, + id: "com.atproto.identity.signPlcOperation", + defs: { + main: { + type: "procedure", + description: + "Signs a PLC operation to update some value(s) in the requesting DID's document.", + input: { + encoding: "application/json", + schema: { + type: "object", + properties: { + token: { + description: + "A token received through com.atproto.identity.requestPlcOperationSignature", + type: "string", + }, + rotationKeys: { + type: "array", + items: { + type: "string", + }, + }, + alsoKnownAs: { + type: "array", + items: { + type: "string", + }, + }, + verificationMethods: { + type: "unknown", + }, + services: { + type: "unknown", + }, + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["operation"], + properties: { + operation: { + type: "unknown", + description: "A signed DID PLC operation.", + }, + }, + }, + }, + }, + }, + }, + ComAtprotoIdentitySubmitPlcOperation: { + lexicon: 1, + id: "com.atproto.identity.submitPlcOperation", + defs: { + main: { + type: "procedure", + description: + "Validates a PLC operation to ensure that it doesn't violate a service's constraints or get the identity into a bad state, then submits it to the PLC registry", + input: { + encoding: "application/json", + schema: { + type: "object", + required: ["operation"], + properties: { + operation: { + type: "unknown", + }, + }, + }, + }, + }, + }, + }, + ComAtprotoIdentityUpdateHandle: { + lexicon: 1, + id: "com.atproto.identity.updateHandle", + defs: { + main: { + type: "procedure", + description: + "Updates the current account's handle. Verifies handle validity, and updates did:plc document if necessary. Implemented by PDS, and requires auth.", + input: { + encoding: "application/json", + schema: { + type: "object", + required: ["handle"], + properties: { + handle: { + type: "string", + format: "handle", + description: "The new handle.", + }, + }, + }, + }, + }, + }, + }, + ComAtprotoLabelDefs: { + lexicon: 1, + id: "com.atproto.label.defs", + defs: { + label: { + type: "object", + description: + "Metadata tag on an atproto resource (eg, repo or record).", + required: ["src", "uri", "val", "cts"], + properties: { + ver: { + type: "integer", + description: "The AT Protocol version of the label object.", + }, + src: { + type: "string", + format: "did", + description: "DID of the actor who created this label.", + }, + uri: { + type: "string", + format: "uri", + description: + "AT URI of the record, repository (account), or other resource that this label applies to.", + }, + cid: { + type: "string", + format: "cid", + description: + "Optionally, CID specifying the specific version of 'uri' resource this label applies to.", + }, + val: { + type: "string", + maxLength: 128, + description: + "The short string name of the value or type of this label.", + }, + neg: { + type: "boolean", + description: + "If true, this is a negation label, overwriting a previous label.", + }, + cts: { + type: "string", + format: "datetime", + description: "Timestamp when this label was created.", + }, + exp: { + type: "string", + format: "datetime", + description: + "Timestamp at which this label expires (no longer applies).", + }, + sig: { + type: "bytes", + description: "Signature of dag-cbor encoded label.", + }, + }, + }, + selfLabels: { + type: "object", + description: + "Metadata tags on an atproto record, published by the author within the record.", + required: ["values"], + properties: { + values: { + type: "array", + items: { + type: "ref", + ref: "lex:com.atproto.label.defs#selfLabel", + }, + maxLength: 10, + }, + }, + }, + selfLabel: { + type: "object", + description: + "Metadata tag on an atproto record, published by the author within the record. Note that schemas should use #selfLabels, not #selfLabel.", + required: ["val"], + properties: { + val: { + type: "string", + maxLength: 128, + description: + "The short string name of the value or type of this label.", + }, + }, + }, + labelValueDefinition: { + type: "object", + description: + "Declares a label value and its expected interpretations and behaviors.", + required: ["identifier", "severity", "blurs", "locales"], + properties: { + identifier: { + type: "string", + description: + "The value of the label being defined. Must only include lowercase ascii and the '-' character ([a-z-]+).", + maxLength: 100, + maxGraphemes: 100, + }, + severity: { + type: "string", + description: + "How should a client visually convey this label? 'inform' means neutral and informational; 'alert' means negative and warning; 'none' means show nothing.", + knownValues: ["inform", "alert", "none"], + }, + blurs: { + type: "string", + description: + "What should this label hide in the UI, if applied? 'content' hides all of the target; 'media' hides the images/video/audio; 'none' hides nothing.", + knownValues: ["content", "media", "none"], + }, + defaultSetting: { + type: "string", + description: "The default setting for this label.", + knownValues: ["ignore", "warn", "hide"], + default: "warn", + }, + adultOnly: { + type: "boolean", + description: + "Does the user need to have adult content enabled in order to configure this label?", + }, + locales: { + type: "array", + items: { + type: "ref", + ref: "lex:com.atproto.label.defs#labelValueDefinitionStrings", + }, + }, + }, + }, + labelValueDefinitionStrings: { + type: "object", + description: + "Strings which describe the label in the UI, localized into a specific language.", + required: ["lang", "name", "description"], + properties: { + lang: { + type: "string", + description: + "The code of the language these strings are written in.", + format: "language", + }, + name: { + type: "string", + description: "A short human-readable name for the label.", + maxGraphemes: 64, + maxLength: 640, + }, + description: { + type: "string", + description: + "A longer description of what the label means and why it might be applied.", + maxGraphemes: 10000, + maxLength: 100000, + }, + }, + }, + labelValue: { + type: "string", + knownValues: [ + "!hide", + "!no-promote", + "!warn", + "!no-unauthenticated", + "dmca-violation", + "doxxing", + "porn", + "sexual", + "nudity", + "nsfl", + "gore", + ], + }, + }, + }, + ComAtprotoLabelQueryLabels: { + lexicon: 1, + id: "com.atproto.label.queryLabels", + defs: { + main: { + type: "query", + description: + "Find labels relevant to the provided AT-URI patterns. Public endpoint for moderation services, though may return different or additional results with auth.", + parameters: { + type: "params", + required: ["uriPatterns"], + properties: { + uriPatterns: { + type: "array", + items: { + type: "string", + }, + description: + "List of AT URI patterns to match (boolean 'OR'). Each may be a prefix (ending with '*'; will match inclusive of the string leading to '*'), or a full URI.", + }, + sources: { + type: "array", + items: { + type: "string", + format: "did", + }, + description: + "Optional list of label sources (DIDs) to filter on.", + }, + limit: { + type: "integer", + minimum: 1, + maximum: 250, + default: 50, + }, + cursor: { + type: "string", + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["labels"], + properties: { + cursor: { + type: "string", + }, + labels: { + type: "array", + items: { + type: "ref", + ref: "lex:com.atproto.label.defs#label", + }, + }, + }, + }, + }, + }, + }, + }, + ComAtprotoLabelSubscribeLabels: { + lexicon: 1, + id: "com.atproto.label.subscribeLabels", + defs: { + main: { + type: "subscription", + description: + "Subscribe to stream of labels (and negations). Public endpoint implemented by mod services. Uses same sequencing scheme as repo event stream.", + parameters: { + type: "params", + properties: { + cursor: { + type: "integer", + description: "The last known event seq number to backfill from.", + }, + }, + }, + message: { + schema: { + type: "union", + refs: [ + "lex:com.atproto.label.subscribeLabels#labels", + "lex:com.atproto.label.subscribeLabels#info", + ], + }, + }, + errors: [ + { + name: "FutureCursor", + }, + ], + }, + labels: { + type: "object", + required: ["seq", "labels"], + properties: { + seq: { + type: "integer", + }, + labels: { + type: "array", + items: { + type: "ref", + ref: "lex:com.atproto.label.defs#label", + }, + }, + }, + }, + info: { + type: "object", + required: ["name"], + properties: { + name: { + type: "string", + knownValues: ["OutdatedCursor"], + }, + message: { + type: "string", + }, + }, + }, + }, + }, + ComAtprotoLexiconSchema: { + lexicon: 1, + id: "com.atproto.lexicon.schema", + defs: { + main: { + type: "record", + description: + "Representation of Lexicon schemas themselves, when published as atproto records. Note that the schema language is not defined in Lexicon; this meta schema currently only includes a single version field ('lexicon'). See the atproto specifications for description of the other expected top-level fields ('id', 'defs', etc).", + key: "nsid", + record: { + type: "object", + required: ["lexicon"], + properties: { + lexicon: { + type: "integer", + description: + "Indicates the 'version' of the Lexicon language. Must be '1' for the current atproto/Lexicon schema system.", + }, + }, + }, + }, + }, + }, + ComAtprotoModerationCreateReport: { + lexicon: 1, + id: "com.atproto.moderation.createReport", + defs: { + main: { + type: "procedure", + description: + "Submit a moderation report regarding an atproto account or record. Implemented by moderation services (with PDS proxying), and requires auth.", + input: { + encoding: "application/json", + schema: { + type: "object", + required: ["reasonType", "subject"], + properties: { + reasonType: { + type: "ref", + description: + "Indicates the broad category of violation the report is for.", + ref: "lex:com.atproto.moderation.defs#reasonType", + }, + reason: { + type: "string", + maxGraphemes: 2000, + maxLength: 20000, + description: + "Additional context about the content and violation.", + }, + subject: { + type: "union", + refs: [ + "lex:com.atproto.admin.defs#repoRef", + "lex:com.atproto.repo.strongRef", + ], + }, + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: [ + "id", + "reasonType", + "subject", + "reportedBy", + "createdAt", + ], + properties: { + id: { + type: "integer", + }, + reasonType: { + type: "ref", + ref: "lex:com.atproto.moderation.defs#reasonType", + }, + reason: { + type: "string", + maxGraphemes: 2000, + maxLength: 20000, + }, + subject: { + type: "union", + refs: [ + "lex:com.atproto.admin.defs#repoRef", + "lex:com.atproto.repo.strongRef", + ], + }, + reportedBy: { + type: "string", + format: "did", + }, + createdAt: { + type: "string", + format: "datetime", + }, + }, + }, + }, + }, + }, + }, + ComAtprotoModerationDefs: { + lexicon: 1, + id: "com.atproto.moderation.defs", + defs: { + reasonType: { + type: "string", + knownValues: [ + "com.atproto.moderation.defs#reasonSpam", + "com.atproto.moderation.defs#reasonViolation", + "com.atproto.moderation.defs#reasonMisleading", + "com.atproto.moderation.defs#reasonSexual", + "com.atproto.moderation.defs#reasonRude", + "com.atproto.moderation.defs#reasonOther", + "com.atproto.moderation.defs#reasonAppeal", + ], + }, + reasonSpam: { + type: "token", + description: "Spam: frequent unwanted promotion, replies, mentions", + }, + reasonViolation: { + type: "token", + description: "Direct violation of server rules, laws, terms of service", + }, + reasonMisleading: { + type: "token", + description: "Misleading identity, affiliation, or content", + }, + reasonSexual: { + type: "token", + description: "Unwanted or mislabeled sexual content", + }, + reasonRude: { + type: "token", + description: + "Rude, harassing, explicit, or otherwise unwelcoming behavior", + }, + reasonOther: { + type: "token", + description: "Other: reports not falling under another report category", + }, + reasonAppeal: { + type: "token", + description: "Appeal: appeal a previously taken moderation action", + }, + }, + }, + ComAtprotoRepoApplyWrites: { + lexicon: 1, + id: "com.atproto.repo.applyWrites", + defs: { + main: { + type: "procedure", + description: + "Apply a batch transaction of repository creates, updates, and deletes. Requires auth, implemented by PDS.", + input: { + encoding: "application/json", + schema: { + type: "object", + required: ["repo", "writes"], + properties: { + repo: { + type: "string", + format: "at-identifier", + description: + "The handle or DID of the repo (aka, current account).", + }, + validate: { + type: "boolean", + description: + "Can be set to 'false' to skip Lexicon schema validation of record data across all operations, 'true' to require it, or leave unset to validate only for known Lexicons.", + }, + writes: { + type: "array", + items: { + type: "union", + refs: [ + "lex:com.atproto.repo.applyWrites#create", + "lex:com.atproto.repo.applyWrites#update", + "lex:com.atproto.repo.applyWrites#delete", + ], + closed: true, + }, + }, + swapCommit: { + type: "string", + description: + "If provided, the entire operation will fail if the current repo commit CID does not match this value. Used to prevent conflicting repo mutations.", + format: "cid", + }, + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: [], + properties: { + commit: { + type: "ref", + ref: "lex:com.atproto.repo.defs#commitMeta", + }, + results: { + type: "array", + items: { + type: "union", + refs: [ + "lex:com.atproto.repo.applyWrites#createResult", + "lex:com.atproto.repo.applyWrites#updateResult", + "lex:com.atproto.repo.applyWrites#deleteResult", + ], + closed: true, + }, + }, + }, + }, + }, + errors: [ + { + name: "InvalidSwap", + description: + "Indicates that the 'swapCommit' parameter did not match current commit.", + }, + ], + }, + create: { + type: "object", + description: "Operation which creates a new record.", + required: ["collection", "value"], + properties: { + collection: { + type: "string", + format: "nsid", + }, + rkey: { + type: "string", + maxLength: 512, + }, + value: { + type: "unknown", + }, + }, + }, + update: { + type: "object", + description: "Operation which updates an existing record.", + required: ["collection", "rkey", "value"], + properties: { + collection: { + type: "string", + format: "nsid", + }, + rkey: { + type: "string", + }, + value: { + type: "unknown", + }, + }, + }, + delete: { + type: "object", + description: "Operation which deletes an existing record.", + required: ["collection", "rkey"], + properties: { + collection: { + type: "string", + format: "nsid", + }, + rkey: { + type: "string", + }, + }, + }, + createResult: { + type: "object", + required: ["uri", "cid"], + properties: { + uri: { + type: "string", + format: "at-uri", + }, + cid: { + type: "string", + format: "cid", + }, + validationStatus: { + type: "string", + knownValues: ["valid", "unknown"], + }, + }, + }, + updateResult: { + type: "object", + required: ["uri", "cid"], + properties: { + uri: { + type: "string", + format: "at-uri", + }, + cid: { + type: "string", + format: "cid", + }, + validationStatus: { + type: "string", + knownValues: ["valid", "unknown"], + }, + }, + }, + deleteResult: { + type: "object", + required: [], + properties: {}, + }, + }, + }, + ComAtprotoRepoCreateRecord: { + lexicon: 1, + id: "com.atproto.repo.createRecord", + defs: { + main: { + type: "procedure", + description: + "Create a single new repository record. Requires auth, implemented by PDS.", + input: { + encoding: "application/json", + schema: { + type: "object", + required: ["repo", "collection", "record"], + properties: { + repo: { + type: "string", + format: "at-identifier", + description: + "The handle or DID of the repo (aka, current account).", + }, + collection: { + type: "string", + format: "nsid", + description: "The NSID of the record collection.", + }, + rkey: { + type: "string", + description: "The Record Key.", + maxLength: 512, + }, + validate: { + type: "boolean", + description: + "Can be set to 'false' to skip Lexicon schema validation of record data, 'true' to require it, or leave unset to validate only for known Lexicons.", + }, + record: { + type: "unknown", + description: "The record itself. Must contain a $type field.", + }, + swapCommit: { + type: "string", + format: "cid", + description: + "Compare and swap with the previous commit by CID.", + }, + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["uri", "cid"], + properties: { + uri: { + type: "string", + format: "at-uri", + }, + cid: { + type: "string", + format: "cid", + }, + commit: { + type: "ref", + ref: "lex:com.atproto.repo.defs#commitMeta", + }, + validationStatus: { + type: "string", + knownValues: ["valid", "unknown"], + }, + }, + }, + }, + errors: [ + { + name: "InvalidSwap", + description: + "Indicates that 'swapCommit' didn't match current repo commit.", + }, + ], + }, + }, + }, + ComAtprotoRepoDefs: { + lexicon: 1, + id: "com.atproto.repo.defs", + defs: { + commitMeta: { + type: "object", + required: ["cid", "rev"], + properties: { + cid: { + type: "string", + format: "cid", + }, + rev: { + type: "string", + }, + }, + }, + }, + }, + ComAtprotoRepoDeleteRecord: { + lexicon: 1, + id: "com.atproto.repo.deleteRecord", + defs: { + main: { + type: "procedure", + description: + "Delete a repository record, or ensure it doesn't exist. Requires auth, implemented by PDS.", + input: { + encoding: "application/json", + schema: { + type: "object", + required: ["repo", "collection", "rkey"], + properties: { + repo: { + type: "string", + format: "at-identifier", + description: + "The handle or DID of the repo (aka, current account).", + }, + collection: { + type: "string", + format: "nsid", + description: "The NSID of the record collection.", + }, + rkey: { + type: "string", + description: "The Record Key.", + }, + swapRecord: { + type: "string", + format: "cid", + description: + "Compare and swap with the previous record by CID.", + }, + swapCommit: { + type: "string", + format: "cid", + description: + "Compare and swap with the previous commit by CID.", + }, + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + properties: { + commit: { + type: "ref", + ref: "lex:com.atproto.repo.defs#commitMeta", + }, + }, + }, + }, + errors: [ + { + name: "InvalidSwap", + }, + ], + }, + }, + }, + ComAtprotoRepoDescribeRepo: { + lexicon: 1, + id: "com.atproto.repo.describeRepo", + defs: { + main: { + type: "query", + description: + "Get information about an account and repository, including the list of collections. Does not require auth.", + parameters: { + type: "params", + required: ["repo"], + properties: { + repo: { + type: "string", + format: "at-identifier", + description: "The handle or DID of the repo.", + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: [ + "handle", + "did", + "didDoc", + "collections", + "handleIsCorrect", + ], + properties: { + handle: { + type: "string", + format: "handle", + }, + did: { + type: "string", + format: "did", + }, + didDoc: { + type: "unknown", + description: "The complete DID document for this account.", + }, + collections: { + type: "array", + description: + "List of all the collections (NSIDs) for which this repo contains at least one record.", + items: { + type: "string", + format: "nsid", + }, + }, + handleIsCorrect: { + type: "boolean", + description: + "Indicates if handle is currently valid (resolves bi-directionally)", + }, + }, + }, + }, + }, + }, + }, + ComAtprotoRepoGetRecord: { + lexicon: 1, + id: "com.atproto.repo.getRecord", + defs: { + main: { + type: "query", + description: + "Get a single record from a repository. Does not require auth.", + parameters: { + type: "params", + required: ["repo", "collection", "rkey"], + properties: { + repo: { + type: "string", + format: "at-identifier", + description: "The handle or DID of the repo.", + }, + collection: { + type: "string", + format: "nsid", + description: "The NSID of the record collection.", + }, + rkey: { + type: "string", + description: "The Record Key.", + }, + cid: { + type: "string", + format: "cid", + description: + "The CID of the version of the record. If not specified, then return the most recent version.", + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["uri", "value"], + properties: { + uri: { + type: "string", + format: "at-uri", + }, + cid: { + type: "string", + format: "cid", + }, + value: { + type: "unknown", + }, + }, + }, + }, + errors: [ + { + name: "RecordNotFound", + }, + ], + }, + }, + }, + ComAtprotoRepoImportRepo: { + lexicon: 1, + id: "com.atproto.repo.importRepo", + defs: { + main: { + type: "procedure", + description: + "Import a repo in the form of a CAR file. Requires Content-Length HTTP header to be set.", + input: { + encoding: "application/vnd.ipld.car", + }, + }, + }, + }, + ComAtprotoRepoListMissingBlobs: { + lexicon: 1, + id: "com.atproto.repo.listMissingBlobs", + defs: { + main: { + type: "query", + description: + "Returns a list of missing blobs for the requesting account. Intended to be used in the account migration flow.", + parameters: { + type: "params", + properties: { + limit: { + type: "integer", + minimum: 1, + maximum: 1000, + default: 500, + }, + cursor: { + type: "string", + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["blobs"], + properties: { + cursor: { + type: "string", + }, + blobs: { + type: "array", + items: { + type: "ref", + ref: "lex:com.atproto.repo.listMissingBlobs#recordBlob", + }, + }, + }, + }, + }, + }, + recordBlob: { + type: "object", + required: ["cid", "recordUri"], + properties: { + cid: { + type: "string", + format: "cid", + }, + recordUri: { + type: "string", + format: "at-uri", + }, + }, + }, + }, + }, + ComAtprotoRepoListRecords: { + lexicon: 1, + id: "com.atproto.repo.listRecords", + defs: { + main: { + type: "query", + description: + "List a range of records in a repository, matching a specific collection. Does not require auth.", + parameters: { + type: "params", + required: ["repo", "collection"], + properties: { + repo: { + type: "string", + format: "at-identifier", + description: "The handle or DID of the repo.", + }, + collection: { + type: "string", + format: "nsid", + description: "The NSID of the record type.", + }, + limit: { + type: "integer", + minimum: 1, + maximum: 100, + default: 50, + description: "The number of records to return.", + }, + cursor: { + type: "string", + }, + rkeyStart: { + type: "string", + description: + "DEPRECATED: The lowest sort-ordered rkey to start from (exclusive)", + }, + rkeyEnd: { + type: "string", + description: + "DEPRECATED: The highest sort-ordered rkey to stop at (exclusive)", + }, + reverse: { + type: "boolean", + description: "Flag to reverse the order of the returned records.", + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["records"], + properties: { + cursor: { + type: "string", + }, + records: { + type: "array", + items: { + type: "ref", + ref: "lex:com.atproto.repo.listRecords#record", + }, + }, + }, + }, + }, + }, + record: { + type: "object", + required: ["uri", "cid", "value"], + properties: { + uri: { + type: "string", + format: "at-uri", + }, + cid: { + type: "string", + format: "cid", + }, + value: { + type: "unknown", + }, + }, + }, + }, + }, + ComAtprotoRepoPutRecord: { + lexicon: 1, + id: "com.atproto.repo.putRecord", + defs: { + main: { + type: "procedure", + description: + "Write a repository record, creating or updating it as needed. Requires auth, implemented by PDS.", + input: { + encoding: "application/json", + schema: { + type: "object", + required: ["repo", "collection", "rkey", "record"], + nullable: ["swapRecord"], + properties: { + repo: { + type: "string", + format: "at-identifier", + description: + "The handle or DID of the repo (aka, current account).", + }, + collection: { + type: "string", + format: "nsid", + description: "The NSID of the record collection.", + }, + rkey: { + type: "string", + description: "The Record Key.", + maxLength: 512, + }, + validate: { + type: "boolean", + description: + "Can be set to 'false' to skip Lexicon schema validation of record data, 'true' to require it, or leave unset to validate only for known Lexicons.", + }, + record: { + type: "unknown", + description: "The record to write.", + }, + swapRecord: { + type: "string", + format: "cid", + description: + "Compare and swap with the previous record by CID. WARNING: nullable and optional field; may cause problems with golang implementation", + }, + swapCommit: { + type: "string", + format: "cid", + description: + "Compare and swap with the previous commit by CID.", + }, + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["uri", "cid"], + properties: { + uri: { + type: "string", + format: "at-uri", + }, + cid: { + type: "string", + format: "cid", + }, + commit: { + type: "ref", + ref: "lex:com.atproto.repo.defs#commitMeta", + }, + validationStatus: { + type: "string", + knownValues: ["valid", "unknown"], + }, + }, + }, + }, + errors: [ + { + name: "InvalidSwap", + }, + ], + }, + }, + }, + ComAtprotoRepoStrongRef: { + lexicon: 1, + id: "com.atproto.repo.strongRef", + description: "A URI with a content-hash fingerprint.", + defs: { + main: { + type: "object", + required: ["uri", "cid"], + properties: { + uri: { + type: "string", + format: "at-uri", + }, + cid: { + type: "string", + format: "cid", + }, + }, + }, + }, + }, + ComAtprotoRepoUploadBlob: { + lexicon: 1, + id: "com.atproto.repo.uploadBlob", + defs: { + main: { + type: "procedure", + description: + "Upload a new blob, to be referenced from a repository record. The blob will be deleted if it is not referenced within a time window (eg, minutes). Blob restrictions (mimetype, size, etc) are enforced when the reference is created. Requires auth, implemented by PDS.", + input: { + encoding: "*/*", + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["blob"], + properties: { + blob: { + type: "blob", + }, + }, + }, + }, + }, + }, + }, + ComAtprotoServerActivateAccount: { + lexicon: 1, + id: "com.atproto.server.activateAccount", + defs: { + main: { + type: "procedure", + description: + "Activates a currently deactivated account. Used to finalize account migration after the account's repo is imported and identity is setup.", + }, + }, + }, + ComAtprotoServerCheckAccountStatus: { + lexicon: 1, + id: "com.atproto.server.checkAccountStatus", + defs: { + main: { + type: "query", + description: + "Returns the status of an account, especially as pertaining to import or recovery. Can be called many times over the course of an account migration. Requires auth and can only be called pertaining to oneself.", + output: { + encoding: "application/json", + schema: { + type: "object", + required: [ + "activated", + "validDid", + "repoCommit", + "repoRev", + "repoBlocks", + "indexedRecords", + "privateStateValues", + "expectedBlobs", + "importedBlobs", + ], + properties: { + activated: { + type: "boolean", + }, + validDid: { + type: "boolean", + }, + repoCommit: { + type: "string", + format: "cid", + }, + repoRev: { + type: "string", + }, + repoBlocks: { + type: "integer", + }, + indexedRecords: { + type: "integer", + }, + privateStateValues: { + type: "integer", + }, + expectedBlobs: { + type: "integer", + }, + importedBlobs: { + type: "integer", + }, + }, + }, + }, + }, + }, + }, + ComAtprotoServerConfirmEmail: { + lexicon: 1, + id: "com.atproto.server.confirmEmail", + defs: { + main: { + type: "procedure", + description: + "Confirm an email using a token from com.atproto.server.requestEmailConfirmation.", + input: { + encoding: "application/json", + schema: { + type: "object", + required: ["email", "token"], + properties: { + email: { + type: "string", + }, + token: { + type: "string", + }, + }, + }, + }, + errors: [ + { + name: "AccountNotFound", + }, + { + name: "ExpiredToken", + }, + { + name: "InvalidToken", + }, + { + name: "InvalidEmail", + }, + ], + }, + }, + }, + ComAtprotoServerCreateAccount: { + lexicon: 1, + id: "com.atproto.server.createAccount", + defs: { + main: { + type: "procedure", + description: "Create an account. Implemented by PDS.", + input: { + encoding: "application/json", + schema: { + type: "object", + required: ["handle"], + properties: { + email: { + type: "string", + }, + handle: { + type: "string", + format: "handle", + description: "Requested handle for the account.", + }, + did: { + type: "string", + format: "did", + description: + "Pre-existing atproto DID, being imported to a new account.", + }, + inviteCode: { + type: "string", + }, + verificationCode: { + type: "string", + }, + verificationPhone: { + type: "string", + }, + password: { + type: "string", + description: + "Initial account password. May need to meet instance-specific password strength requirements.", + }, + recoveryKey: { + type: "string", + description: + "DID PLC rotation key (aka, recovery key) to be included in PLC creation operation.", + }, + plcOp: { + type: "unknown", + description: + "A signed DID PLC operation to be submitted as part of importing an existing account to this instance. NOTE: this optional field may be updated when full account migration is implemented.", + }, + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + description: + "Account login session returned on successful account creation.", + required: ["accessJwt", "refreshJwt", "handle", "did"], + properties: { + accessJwt: { + type: "string", + }, + refreshJwt: { + type: "string", + }, + handle: { + type: "string", + format: "handle", + }, + did: { + type: "string", + format: "did", + description: "The DID of the new account.", + }, + didDoc: { + type: "unknown", + description: "Complete DID document.", + }, + }, + }, + }, + errors: [ + { + name: "InvalidHandle", + }, + { + name: "InvalidPassword", + }, + { + name: "InvalidInviteCode", + }, + { + name: "HandleNotAvailable", + }, + { + name: "UnsupportedDomain", + }, + { + name: "UnresolvableDid", + }, + { + name: "IncompatibleDidDoc", + }, + ], + }, + }, + }, + ComAtprotoServerCreateAppPassword: { + lexicon: 1, + id: "com.atproto.server.createAppPassword", + defs: { + main: { + type: "procedure", + description: "Create an App Password.", + input: { + encoding: "application/json", + schema: { + type: "object", + required: ["name"], + properties: { + name: { + type: "string", + description: + "A short name for the App Password, to help distinguish them.", + }, + privileged: { + type: "boolean", + description: + "If an app password has 'privileged' access to possibly sensitive account state. Meant for use with trusted clients.", + }, + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "ref", + ref: "lex:com.atproto.server.createAppPassword#appPassword", + }, + }, + errors: [ + { + name: "AccountTakedown", + }, + ], + }, + appPassword: { + type: "object", + required: ["name", "password", "createdAt"], + properties: { + name: { + type: "string", + }, + password: { + type: "string", + }, + createdAt: { + type: "string", + format: "datetime", + }, + privileged: { + type: "boolean", + }, + }, + }, + }, + }, + ComAtprotoServerCreateInviteCode: { + lexicon: 1, + id: "com.atproto.server.createInviteCode", + defs: { + main: { + type: "procedure", + description: "Create an invite code.", + input: { + encoding: "application/json", + schema: { + type: "object", + required: ["useCount"], + properties: { + useCount: { + type: "integer", + }, + forAccount: { + type: "string", + format: "did", + }, + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["code"], + properties: { + code: { + type: "string", + }, + }, + }, + }, + }, + }, + }, + ComAtprotoServerCreateInviteCodes: { + lexicon: 1, + id: "com.atproto.server.createInviteCodes", + defs: { + main: { + type: "procedure", + description: "Create invite codes.", + input: { + encoding: "application/json", + schema: { + type: "object", + required: ["codeCount", "useCount"], + properties: { + codeCount: { + type: "integer", + default: 1, + }, + useCount: { + type: "integer", + }, + forAccounts: { + type: "array", + items: { + type: "string", + format: "did", + }, + }, + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["codes"], + properties: { + codes: { + type: "array", + items: { + type: "ref", + ref: "lex:com.atproto.server.createInviteCodes#accountCodes", + }, + }, + }, + }, + }, + }, + accountCodes: { + type: "object", + required: ["account", "codes"], + properties: { + account: { + type: "string", + }, + codes: { + type: "array", + items: { + type: "string", + }, + }, + }, + }, + }, + }, + ComAtprotoServerCreateSession: { + lexicon: 1, + id: "com.atproto.server.createSession", + defs: { + main: { + type: "procedure", + description: "Create an authentication session.", + input: { + encoding: "application/json", + schema: { + type: "object", + required: ["identifier", "password"], + properties: { + identifier: { + type: "string", + description: + "Handle or other identifier supported by the server for the authenticating user.", + }, + password: { + type: "string", + }, + authFactorToken: { + type: "string", + }, + allowTakendown: { + type: "boolean", + description: + "When true, instead of throwing error for takendown accounts, a valid response with a narrow scoped token will be returned", + }, + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["accessJwt", "refreshJwt", "handle", "did"], + properties: { + accessJwt: { + type: "string", + }, + refreshJwt: { + type: "string", + }, + handle: { + type: "string", + format: "handle", + }, + did: { + type: "string", + format: "did", + }, + didDoc: { + type: "unknown", + }, + email: { + type: "string", + }, + emailConfirmed: { + type: "boolean", + }, + emailAuthFactor: { + type: "boolean", + }, + active: { + type: "boolean", + }, + status: { + type: "string", + description: + "If active=false, this optional field indicates a possible reason for why the account is not active. If active=false and no status is supplied, then the host makes no claim for why the repository is no longer being hosted.", + knownValues: ["takendown", "suspended", "deactivated"], + }, + }, + }, + }, + errors: [ + { + name: "AccountTakedown", + }, + { + name: "AuthFactorTokenRequired", + }, + ], + }, + }, + }, + ComAtprotoServerDeactivateAccount: { + lexicon: 1, + id: "com.atproto.server.deactivateAccount", + defs: { + main: { + type: "procedure", + description: + "Deactivates a currently active account. Stops serving of repo, and future writes to repo until reactivated. Used to finalize account migration with the old host after the account has been activated on the new host.", + input: { + encoding: "application/json", + schema: { + type: "object", + properties: { + deleteAfter: { + type: "string", + format: "datetime", + description: + "A recommendation to server as to how long they should hold onto the deactivated account before deleting.", + }, + }, + }, + }, + }, + }, + }, + ComAtprotoServerDefs: { + lexicon: 1, + id: "com.atproto.server.defs", + defs: { + inviteCode: { + type: "object", + required: [ + "code", + "available", + "disabled", + "forAccount", + "createdBy", + "createdAt", + "uses", + ], + properties: { + code: { + type: "string", + }, + available: { + type: "integer", + }, + disabled: { + type: "boolean", + }, + forAccount: { + type: "string", + }, + createdBy: { + type: "string", + }, + createdAt: { + type: "string", + format: "datetime", + }, + uses: { + type: "array", + items: { + type: "ref", + ref: "lex:com.atproto.server.defs#inviteCodeUse", + }, + }, + }, + }, + inviteCodeUse: { + type: "object", + required: ["usedBy", "usedAt"], + properties: { + usedBy: { + type: "string", + format: "did", + }, + usedAt: { + type: "string", + format: "datetime", + }, + }, + }, + }, + }, + ComAtprotoServerDeleteAccount: { + lexicon: 1, + id: "com.atproto.server.deleteAccount", + defs: { + main: { + type: "procedure", + description: + "Delete an actor's account with a token and password. Can only be called after requesting a deletion token. Requires auth.", + input: { + encoding: "application/json", + schema: { + type: "object", + required: ["did", "password", "token"], + properties: { + did: { + type: "string", + format: "did", + }, + password: { + type: "string", + }, + token: { + type: "string", + }, + }, + }, + }, + errors: [ + { + name: "ExpiredToken", + }, + { + name: "InvalidToken", + }, + ], + }, + }, + }, + ComAtprotoServerDeleteSession: { + lexicon: 1, + id: "com.atproto.server.deleteSession", + defs: { + main: { + type: "procedure", + description: "Delete the current session. Requires auth.", + }, + }, + }, + ComAtprotoServerDescribeServer: { + lexicon: 1, + id: "com.atproto.server.describeServer", + defs: { + main: { + type: "query", + description: + "Describes the server's account creation requirements and capabilities. Implemented by PDS.", + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["did", "availableUserDomains"], + properties: { + inviteCodeRequired: { + type: "boolean", + description: + "If true, an invite code must be supplied to create an account on this instance.", + }, + phoneVerificationRequired: { + type: "boolean", + description: + "If true, a phone verification token must be supplied to create an account on this instance.", + }, + availableUserDomains: { + type: "array", + description: + "List of domain suffixes that can be used in account handles.", + items: { + type: "string", + }, + }, + links: { + type: "ref", + description: "URLs of service policy documents.", + ref: "lex:com.atproto.server.describeServer#links", + }, + contact: { + type: "ref", + description: "Contact information", + ref: "lex:com.atproto.server.describeServer#contact", + }, + did: { + type: "string", + format: "did", + }, + }, + }, + }, + }, + links: { + type: "object", + properties: { + privacyPolicy: { + type: "string", + format: "uri", + }, + termsOfService: { + type: "string", + format: "uri", + }, + }, + }, + contact: { + type: "object", + properties: { + email: { + type: "string", + }, + }, + }, + }, + }, + ComAtprotoServerGetAccountInviteCodes: { + lexicon: 1, + id: "com.atproto.server.getAccountInviteCodes", + defs: { + main: { + type: "query", + description: + "Get all invite codes for the current account. Requires auth.", + parameters: { + type: "params", + properties: { + includeUsed: { + type: "boolean", + default: true, + }, + createAvailable: { + type: "boolean", + default: true, + description: + "Controls whether any new 'earned' but not 'created' invites should be created.", + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["codes"], + properties: { + codes: { + type: "array", + items: { + type: "ref", + ref: "lex:com.atproto.server.defs#inviteCode", + }, + }, + }, + }, + }, + errors: [ + { + name: "DuplicateCreate", + }, + ], + }, + }, + }, + ComAtprotoServerGetServiceAuth: { + lexicon: 1, + id: "com.atproto.server.getServiceAuth", + defs: { + main: { + type: "query", + description: + "Get a signed token on behalf of the requesting DID for the requested service.", + parameters: { + type: "params", + required: ["aud"], + properties: { + aud: { + type: "string", + format: "did", + description: + "The DID of the service that the token will be used to authenticate with", + }, + exp: { + type: "integer", + description: + "The time in Unix Epoch seconds that the JWT expires. Defaults to 60 seconds in the future. The service may enforce certain time bounds on tokens depending on the requested scope.", + }, + lxm: { + type: "string", + format: "nsid", + description: + "Lexicon (XRPC) method to bind the requested token to", + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["token"], + properties: { + token: { + type: "string", + }, + }, + }, + }, + errors: [ + { + name: "BadExpiration", + description: + "Indicates that the requested expiration date is not a valid. May be in the past or may be reliant on the requested scopes.", + }, + ], + }, + }, + }, + ComAtprotoServerGetSession: { + lexicon: 1, + id: "com.atproto.server.getSession", + defs: { + main: { + type: "query", + description: + "Get information about the current auth session. Requires auth.", + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["handle", "did"], + properties: { + handle: { + type: "string", + format: "handle", + }, + did: { + type: "string", + format: "did", + }, + email: { + type: "string", + }, + emailConfirmed: { + type: "boolean", + }, + emailAuthFactor: { + type: "boolean", + }, + didDoc: { + type: "unknown", + }, + active: { + type: "boolean", + }, + status: { + type: "string", + description: + "If active=false, this optional field indicates a possible reason for why the account is not active. If active=false and no status is supplied, then the host makes no claim for why the repository is no longer being hosted.", + knownValues: ["takendown", "suspended", "deactivated"], + }, + }, + }, + }, + }, + }, + }, + ComAtprotoServerListAppPasswords: { + lexicon: 1, + id: "com.atproto.server.listAppPasswords", + defs: { + main: { + type: "query", + description: "List all App Passwords.", + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["passwords"], + properties: { + passwords: { + type: "array", + items: { + type: "ref", + ref: "lex:com.atproto.server.listAppPasswords#appPassword", + }, + }, + }, + }, + }, + errors: [ + { + name: "AccountTakedown", + }, + ], + }, + appPassword: { + type: "object", + required: ["name", "createdAt"], + properties: { + name: { + type: "string", + }, + createdAt: { + type: "string", + format: "datetime", + }, + privileged: { + type: "boolean", + }, + }, + }, + }, + }, + ComAtprotoServerRefreshSession: { + lexicon: 1, + id: "com.atproto.server.refreshSession", + defs: { + main: { + type: "procedure", + description: + "Refresh an authentication session. Requires auth using the 'refreshJwt' (not the 'accessJwt').", + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["accessJwt", "refreshJwt", "handle", "did"], + properties: { + accessJwt: { + type: "string", + }, + refreshJwt: { + type: "string", + }, + handle: { + type: "string", + format: "handle", + }, + did: { + type: "string", + format: "did", + }, + didDoc: { + type: "unknown", + }, + active: { + type: "boolean", + }, + status: { + type: "string", + description: + "Hosting status of the account. If not specified, then assume 'active'.", + knownValues: ["takendown", "suspended", "deactivated"], + }, + }, + }, + }, + errors: [ + { + name: "AccountTakedown", + }, + ], + }, + }, + }, + ComAtprotoServerRequestAccountDelete: { + lexicon: 1, + id: "com.atproto.server.requestAccountDelete", + defs: { + main: { + type: "procedure", + description: "Initiate a user account deletion via email.", + }, + }, + }, + ComAtprotoServerRequestEmailConfirmation: { + lexicon: 1, + id: "com.atproto.server.requestEmailConfirmation", + defs: { + main: { + type: "procedure", + description: + "Request an email with a code to confirm ownership of email.", + }, + }, + }, + ComAtprotoServerRequestEmailUpdate: { + lexicon: 1, + id: "com.atproto.server.requestEmailUpdate", + defs: { + main: { + type: "procedure", + description: "Request a token in order to update email.", + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["tokenRequired"], + properties: { + tokenRequired: { + type: "boolean", + }, + }, + }, + }, + }, + }, + }, + ComAtprotoServerRequestPasswordReset: { + lexicon: 1, + id: "com.atproto.server.requestPasswordReset", + defs: { + main: { + type: "procedure", + description: "Initiate a user account password reset via email.", + input: { + encoding: "application/json", + schema: { + type: "object", + required: ["email"], + properties: { + email: { + type: "string", + }, + }, + }, + }, + }, + }, + }, + ComAtprotoServerReserveSigningKey: { + lexicon: 1, + id: "com.atproto.server.reserveSigningKey", + defs: { + main: { + type: "procedure", + description: + "Reserve a repo signing key, for use with account creation. Necessary so that a DID PLC update operation can be constructed during an account migraiton. Public and does not require auth; implemented by PDS. NOTE: this endpoint may change when full account migration is implemented.", + input: { + encoding: "application/json", + schema: { + type: "object", + properties: { + did: { + type: "string", + format: "did", + description: "The DID to reserve a key for.", + }, + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["signingKey"], + properties: { + signingKey: { + type: "string", + description: + "The public key for the reserved signing key, in did:key serialization.", + }, + }, + }, + }, + }, + }, + }, + ComAtprotoServerResetPassword: { + lexicon: 1, + id: "com.atproto.server.resetPassword", + defs: { + main: { + type: "procedure", + description: "Reset a user account password using a token.", + input: { + encoding: "application/json", + schema: { + type: "object", + required: ["token", "password"], + properties: { + token: { + type: "string", + }, + password: { + type: "string", + }, + }, + }, + }, + errors: [ + { + name: "ExpiredToken", + }, + { + name: "InvalidToken", + }, + ], + }, + }, + }, + ComAtprotoServerRevokeAppPassword: { + lexicon: 1, + id: "com.atproto.server.revokeAppPassword", + defs: { + main: { + type: "procedure", + description: "Revoke an App Password by name.", + input: { + encoding: "application/json", + schema: { + type: "object", + required: ["name"], + properties: { + name: { + type: "string", + }, + }, + }, + }, + }, + }, + }, + ComAtprotoServerUpdateEmail: { + lexicon: 1, + id: "com.atproto.server.updateEmail", + defs: { + main: { + type: "procedure", + description: "Update an account's email.", + input: { + encoding: "application/json", + schema: { + type: "object", + required: ["email"], + properties: { + email: { + type: "string", + }, + emailAuthFactor: { + type: "boolean", + }, + token: { + type: "string", + description: + "Requires a token from com.atproto.sever.requestEmailUpdate if the account's email has been confirmed.", + }, + }, + }, + }, + errors: [ + { + name: "ExpiredToken", + }, + { + name: "InvalidToken", + }, + { + name: "TokenRequired", + }, + ], + }, + }, + }, + ComAtprotoSyncGetBlob: { + lexicon: 1, + id: "com.atproto.sync.getBlob", + defs: { + main: { + type: "query", + description: + "Get a blob associated with a given account. Returns the full blob as originally uploaded. Does not require auth; implemented by PDS.", + parameters: { + type: "params", + required: ["did", "cid"], + properties: { + did: { + type: "string", + format: "did", + description: "The DID of the account.", + }, + cid: { + type: "string", + format: "cid", + description: "The CID of the blob to fetch", + }, + }, + }, + output: { + encoding: "*/*", + }, + errors: [ + { + name: "BlobNotFound", + }, + { + name: "RepoNotFound", + }, + { + name: "RepoTakendown", + }, + { + name: "RepoSuspended", + }, + { + name: "RepoDeactivated", + }, + ], + }, + }, + }, + ComAtprotoSyncGetBlocks: { + lexicon: 1, + id: "com.atproto.sync.getBlocks", + defs: { + main: { + type: "query", + description: + "Get data blocks from a given repo, by CID. For example, intermediate MST nodes, or records. Does not require auth; implemented by PDS.", + parameters: { + type: "params", + required: ["did", "cids"], + properties: { + did: { + type: "string", + format: "did", + description: "The DID of the repo.", + }, + cids: { + type: "array", + items: { + type: "string", + format: "cid", + }, + }, + }, + }, + output: { + encoding: "application/vnd.ipld.car", + }, + errors: [ + { + name: "BlockNotFound", + }, + { + name: "RepoNotFound", + }, + { + name: "RepoTakendown", + }, + { + name: "RepoSuspended", + }, + { + name: "RepoDeactivated", + }, + ], + }, + }, + }, + ComAtprotoSyncGetCheckout: { + lexicon: 1, + id: "com.atproto.sync.getCheckout", + defs: { + main: { + type: "query", + description: "DEPRECATED - please use com.atproto.sync.getRepo instead", + parameters: { + type: "params", + required: ["did"], + properties: { + did: { + type: "string", + format: "did", + description: "The DID of the repo.", + }, + }, + }, + output: { + encoding: "application/vnd.ipld.car", + }, + }, + }, + }, + ComAtprotoSyncGetHead: { + lexicon: 1, + id: "com.atproto.sync.getHead", + defs: { + main: { + type: "query", + description: + "DEPRECATED - please use com.atproto.sync.getLatestCommit instead", + parameters: { + type: "params", + required: ["did"], + properties: { + did: { + type: "string", + format: "did", + description: "The DID of the repo.", + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["root"], + properties: { + root: { + type: "string", + format: "cid", + }, + }, + }, + }, + errors: [ + { + name: "HeadNotFound", + }, + ], + }, + }, + }, + ComAtprotoSyncGetLatestCommit: { + lexicon: 1, + id: "com.atproto.sync.getLatestCommit", + defs: { + main: { + type: "query", + description: + "Get the current commit CID & revision of the specified repo. Does not require auth.", + parameters: { + type: "params", + required: ["did"], + properties: { + did: { + type: "string", + format: "did", + description: "The DID of the repo.", + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["cid", "rev"], + properties: { + cid: { + type: "string", + format: "cid", + }, + rev: { + type: "string", + }, + }, + }, + }, + errors: [ + { + name: "RepoNotFound", + }, + { + name: "RepoTakendown", + }, + { + name: "RepoSuspended", + }, + { + name: "RepoDeactivated", + }, + ], + }, + }, + }, + ComAtprotoSyncGetRecord: { + lexicon: 1, + id: "com.atproto.sync.getRecord", + defs: { + main: { + type: "query", + description: + "Get data blocks needed to prove the existence or non-existence of record in the current version of repo. Does not require auth.", + parameters: { + type: "params", + required: ["did", "collection", "rkey"], + properties: { + did: { + type: "string", + format: "did", + description: "The DID of the repo.", + }, + collection: { + type: "string", + format: "nsid", + }, + rkey: { + type: "string", + description: "Record Key", + }, + commit: { + type: "string", + format: "cid", + description: + "DEPRECATED: referenced a repo commit by CID, and retrieved record as of that commit", + }, + }, + }, + output: { + encoding: "application/vnd.ipld.car", + }, + errors: [ + { + name: "RecordNotFound", + }, + { + name: "RepoNotFound", + }, + { + name: "RepoTakendown", + }, + { + name: "RepoSuspended", + }, + { + name: "RepoDeactivated", + }, + ], + }, + }, + }, + ComAtprotoSyncGetRepo: { + lexicon: 1, + id: "com.atproto.sync.getRepo", + defs: { + main: { + type: "query", + description: + "Download a repository export as CAR file. Optionally only a 'diff' since a previous revision. Does not require auth; implemented by PDS.", + parameters: { + type: "params", + required: ["did"], + properties: { + did: { + type: "string", + format: "did", + description: "The DID of the repo.", + }, + since: { + type: "string", + description: + "The revision ('rev') of the repo to create a diff from.", + }, + }, + }, + output: { + encoding: "application/vnd.ipld.car", + }, + errors: [ + { + name: "RepoNotFound", + }, + { + name: "RepoTakendown", + }, + { + name: "RepoSuspended", + }, + { + name: "RepoDeactivated", + }, + ], + }, + }, + }, + ComAtprotoSyncGetRepoStatus: { + lexicon: 1, + id: "com.atproto.sync.getRepoStatus", + defs: { + main: { + type: "query", + description: + "Get the hosting status for a repository, on this server. Expected to be implemented by PDS and Relay.", + parameters: { + type: "params", + required: ["did"], + properties: { + did: { + type: "string", + format: "did", + description: "The DID of the repo.", + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["did", "active"], + properties: { + did: { + type: "string", + format: "did", + }, + active: { + type: "boolean", + }, + status: { + type: "string", + description: + "If active=false, this optional field indicates a possible reason for why the account is not active. If active=false and no status is supplied, then the host makes no claim for why the repository is no longer being hosted.", + knownValues: ["takendown", "suspended", "deactivated"], + }, + rev: { + type: "string", + description: + "Optional field, the current rev of the repo, if active=true", + }, + }, + }, + }, + errors: [ + { + name: "RepoNotFound", + }, + ], + }, + }, + }, + ComAtprotoSyncListBlobs: { + lexicon: 1, + id: "com.atproto.sync.listBlobs", + defs: { + main: { + type: "query", + description: + "List blob CIDs for an account, since some repo revision. Does not require auth; implemented by PDS.", + parameters: { + type: "params", + required: ["did"], + properties: { + did: { + type: "string", + format: "did", + description: "The DID of the repo.", + }, + since: { + type: "string", + description: "Optional revision of the repo to list blobs since.", + }, + limit: { + type: "integer", + minimum: 1, + maximum: 1000, + default: 500, + }, + cursor: { + type: "string", + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["cids"], + properties: { + cursor: { + type: "string", + }, + cids: { + type: "array", + items: { + type: "string", + format: "cid", + }, + }, + }, + }, + }, + errors: [ + { + name: "RepoNotFound", + }, + { + name: "RepoTakendown", + }, + { + name: "RepoSuspended", + }, + { + name: "RepoDeactivated", + }, + ], + }, + }, + }, + ComAtprotoSyncListReposByCollection: { + lexicon: 1, + id: "com.atproto.sync.listReposByCollection", + defs: { + main: { + type: "query", + description: + "Enumerates all the DIDs which have records with the given collection NSID.", + parameters: { + type: "params", + required: ["collection"], + properties: { + collection: { + type: "string", + format: "nsid", + }, + limit: { + type: "integer", + description: + "Maximum size of response set. Recommend setting a large maximum (1000+) when enumerating large DID lists.", + minimum: 1, + maximum: 2000, + default: 500, + }, + cursor: { + type: "string", + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["repos"], + properties: { + cursor: { + type: "string", + }, + repos: { + type: "array", + items: { + type: "ref", + ref: "lex:com.atproto.sync.listReposByCollection#repo", + }, + }, + }, + }, + }, + }, + repo: { + type: "object", + required: ["did"], + properties: { + did: { + type: "string", + format: "did", + }, + }, + }, + }, + }, + ComAtprotoSyncListRepos: { + lexicon: 1, + id: "com.atproto.sync.listRepos", + defs: { + main: { + type: "query", + description: + "Enumerates all the DID, rev, and commit CID for all repos hosted by this service. Does not require auth; implemented by PDS and Relay.", + parameters: { + type: "params", + properties: { + limit: { + type: "integer", + minimum: 1, + maximum: 1000, + default: 500, + }, + cursor: { + type: "string", + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["repos"], + properties: { + cursor: { + type: "string", + }, + repos: { + type: "array", + items: { + type: "ref", + ref: "lex:com.atproto.sync.listRepos#repo", + }, + }, + }, + }, + }, + }, + repo: { + type: "object", + required: ["did", "head", "rev"], + properties: { + did: { + type: "string", + format: "did", + }, + head: { + type: "string", + format: "cid", + description: "Current repo commit CID", + }, + rev: { + type: "string", + }, + active: { + type: "boolean", + }, + status: { + type: "string", + description: + "If active=false, this optional field indicates a possible reason for why the account is not active. If active=false and no status is supplied, then the host makes no claim for why the repository is no longer being hosted.", + knownValues: ["takendown", "suspended", "deactivated"], + }, + }, + }, + }, + }, + ComAtprotoSyncNotifyOfUpdate: { + lexicon: 1, + id: "com.atproto.sync.notifyOfUpdate", + defs: { + main: { + type: "procedure", + description: + "Notify a crawling service of a recent update, and that crawling should resume. Intended use is after a gap between repo stream events caused the crawling service to disconnect. Does not require auth; implemented by Relay.", + input: { + encoding: "application/json", + schema: { + type: "object", + required: ["hostname"], + properties: { + hostname: { + type: "string", + description: + "Hostname of the current service (usually a PDS) that is notifying of update.", + }, + }, + }, + }, + }, + }, + }, + ComAtprotoSyncRequestCrawl: { + lexicon: 1, + id: "com.atproto.sync.requestCrawl", + defs: { + main: { + type: "procedure", + description: + "Request a service to persistently crawl hosted repos. Expected use is new PDS instances declaring their existence to Relays. Does not require auth.", + input: { + encoding: "application/json", + schema: { + type: "object", + required: ["hostname"], + properties: { + hostname: { + type: "string", + description: + "Hostname of the current service (eg, PDS) that is requesting to be crawled.", + }, + }, + }, + }, + }, + }, + }, + ComAtprotoSyncSubscribeRepos: { + lexicon: 1, + id: "com.atproto.sync.subscribeRepos", + defs: { + main: { + type: "subscription", + description: + "Repository event stream, aka Firehose endpoint. Outputs repo commits with diff data, and identity update events, for all repositories on the current server. See the atproto specifications for details around stream sequencing, repo versioning, CAR diff format, and more. Public and does not require auth; implemented by PDS and Relay.", + parameters: { + type: "params", + properties: { + cursor: { + type: "integer", + description: "The last known event seq number to backfill from.", + }, + }, + }, + message: { + schema: { + type: "union", + refs: [ + "lex:com.atproto.sync.subscribeRepos#commit", + "lex:com.atproto.sync.subscribeRepos#identity", + "lex:com.atproto.sync.subscribeRepos#account", + "lex:com.atproto.sync.subscribeRepos#handle", + "lex:com.atproto.sync.subscribeRepos#migrate", + "lex:com.atproto.sync.subscribeRepos#tombstone", + "lex:com.atproto.sync.subscribeRepos#info", + ], + }, + }, + errors: [ + { + name: "FutureCursor", + }, + { + name: "ConsumerTooSlow", + description: + "If the consumer of the stream can not keep up with events, and a backlog gets too large, the server will drop the connection.", + }, + ], + }, + commit: { + type: "object", + description: + "Represents an update of repository state. Note that empty commits are allowed, which include no repo data changes, but an update to rev and signature.", + required: [ + "seq", + "rebase", + "tooBig", + "repo", + "commit", + "rev", + "since", + "blocks", + "ops", + "blobs", + "time", + ], + nullable: ["prev", "since"], + properties: { + seq: { + type: "integer", + description: "The stream sequence number of this message.", + }, + rebase: { + type: "boolean", + description: "DEPRECATED -- unused", + }, + tooBig: { + type: "boolean", + description: + "Indicates that this commit contained too many ops, or data size was too large. Consumers will need to make a separate request to get missing data.", + }, + repo: { + type: "string", + format: "did", + description: "The repo this event comes from.", + }, + commit: { + type: "cid-link", + description: "Repo commit object CID.", + }, + prev: { + type: "cid-link", + description: + "DEPRECATED -- unused. WARNING -- nullable and optional; stick with optional to ensure golang interoperability.", + }, + rev: { + type: "string", + description: + "The rev of the emitted commit. Note that this information is also in the commit object included in blocks, unless this is a tooBig event.", + }, + since: { + type: "string", + description: + "The rev of the last emitted commit from this repo (if any).", + }, + blocks: { + type: "bytes", + description: + "CAR file containing relevant blocks, as a diff since the previous repo state.", + maxLength: 1000000, + }, + ops: { + type: "array", + items: { + type: "ref", + ref: "lex:com.atproto.sync.subscribeRepos#repoOp", + description: + "List of repo mutation operations in this commit (eg, records created, updated, or deleted).", + }, + maxLength: 200, + }, + blobs: { + type: "array", + items: { + type: "cid-link", + description: + "List of new blobs (by CID) referenced by records in this commit.", + }, + }, + time: { + type: "string", + format: "datetime", + description: + "Timestamp of when this message was originally broadcast.", + }, + }, + }, + identity: { + type: "object", + description: + "Represents a change to an account's identity. Could be an updated handle, signing key, or pds hosting endpoint. Serves as a prod to all downstream services to refresh their identity cache.", + required: ["seq", "did", "time"], + properties: { + seq: { + type: "integer", + }, + did: { + type: "string", + format: "did", + }, + time: { + type: "string", + format: "datetime", + }, + handle: { + type: "string", + format: "handle", + description: + "The current handle for the account, or 'handle.invalid' if validation fails. This field is optional, might have been validated or passed-through from an upstream source. Semantics and behaviors for PDS vs Relay may evolve in the future; see atproto specs for more details.", + }, + }, + }, + account: { + type: "object", + description: + "Represents a change to an account's status on a host (eg, PDS or Relay). The semantics of this event are that the status is at the host which emitted the event, not necessarily that at the currently active PDS. Eg, a Relay takedown would emit a takedown with active=false, even if the PDS is still active.", + required: ["seq", "did", "time", "active"], + properties: { + seq: { + type: "integer", + }, + did: { + type: "string", + format: "did", + }, + time: { + type: "string", + format: "datetime", + }, + active: { + type: "boolean", + description: + "Indicates that the account has a repository which can be fetched from the host that emitted this event.", + }, + status: { + type: "string", + description: + "If active=false, this optional field indicates a reason for why the account is not active.", + knownValues: ["takendown", "suspended", "deleted", "deactivated"], + }, + }, + }, + handle: { + type: "object", + description: "DEPRECATED -- Use #identity event instead", + required: ["seq", "did", "handle", "time"], + properties: { + seq: { + type: "integer", + }, + did: { + type: "string", + format: "did", + }, + handle: { + type: "string", + format: "handle", + }, + time: { + type: "string", + format: "datetime", + }, + }, + }, + migrate: { + type: "object", + description: "DEPRECATED -- Use #account event instead", + required: ["seq", "did", "migrateTo", "time"], + nullable: ["migrateTo"], + properties: { + seq: { + type: "integer", + }, + did: { + type: "string", + format: "did", + }, + migrateTo: { + type: "string", + }, + time: { + type: "string", + format: "datetime", + }, + }, + }, + tombstone: { + type: "object", + description: "DEPRECATED -- Use #account event instead", + required: ["seq", "did", "time"], + properties: { + seq: { + type: "integer", + }, + did: { + type: "string", + format: "did", + }, + time: { + type: "string", + format: "datetime", + }, + }, + }, + info: { + type: "object", + required: ["name"], + properties: { + name: { + type: "string", + knownValues: ["OutdatedCursor"], + }, + message: { + type: "string", + }, + }, + }, + repoOp: { + type: "object", + description: "A repo operation, ie a mutation of a single record.", + required: ["action", "path", "cid"], + nullable: ["cid"], + properties: { + action: { + type: "string", + knownValues: ["create", "update", "delete"], + }, + path: { + type: "string", + }, + cid: { + type: "cid-link", + description: + "For creates and updates, the new record CID. For deletions, null.", + }, + }, + }, + }, + }, + ComAtprotoTempAddReservedHandle: { + lexicon: 1, + id: "com.atproto.temp.addReservedHandle", + defs: { + main: { + type: "procedure", + description: "Add a handle to the set of reserved handles.", + input: { + encoding: "application/json", + schema: { + type: "object", + required: ["handle"], + properties: { + handle: { + type: "string", + }, + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + properties: {}, + }, + }, + }, + }, + }, + ComAtprotoTempCheckSignupQueue: { + lexicon: 1, + id: "com.atproto.temp.checkSignupQueue", + defs: { + main: { + type: "query", + description: "Check accounts location in signup queue.", + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["activated"], + properties: { + activated: { + type: "boolean", + }, + placeInQueue: { + type: "integer", + }, + estimatedTimeMs: { + type: "integer", + }, + }, + }, + }, + }, + }, + }, + ComAtprotoTempFetchLabels: { + lexicon: 1, + id: "com.atproto.temp.fetchLabels", + defs: { + main: { + type: "query", + description: + "DEPRECATED: use queryLabels or subscribeLabels instead -- Fetch all labels from a labeler created after a certain date.", + parameters: { + type: "params", + properties: { + since: { + type: "integer", + }, + limit: { + type: "integer", + minimum: 1, + maximum: 250, + default: 50, + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["labels"], + properties: { + labels: { + type: "array", + items: { + type: "ref", + ref: "lex:com.atproto.label.defs#label", + }, + }, + }, + }, + }, + }, + }, + }, + ComAtprotoTempRequestPhoneVerification: { + lexicon: 1, + id: "com.atproto.temp.requestPhoneVerification", + defs: { + main: { + type: "procedure", + description: + "Request a verification code to be sent to the supplied phone number", + input: { + encoding: "application/json", + schema: { + type: "object", + required: ["phoneNumber"], + properties: { + phoneNumber: { + type: "string", + }, + }, + }, + }, + }, + }, + }, + SoSprkActorDefs: { + lexicon: 1, + id: "so.sprk.actor.defs", + defs: { + profileViewBasic: { + type: "object", + required: ["did", "handle"], + properties: { + did: { + type: "string", + format: "did", + }, + handle: { + type: "string", + format: "handle", + }, + displayName: { + type: "string", + maxGraphemes: 64, + maxLength: 640, + }, + avatar: { + type: "string", + format: "uri", + }, + associated: { + type: "ref", + ref: "lex:so.sprk.actor.defs#profileAssociated", + }, + viewer: { + type: "ref", + ref: "lex:so.sprk.actor.defs#viewerState", + }, + labels: { + type: "array", + items: { + type: "ref", + ref: "lex:com.atproto.label.defs#label", + }, + }, + createdAt: { + type: "string", + format: "datetime", + }, + }, + }, + profileView: { + type: "object", + required: ["did", "handle"], + properties: { + did: { + type: "string", + format: "did", + }, + handle: { + type: "string", + format: "handle", + }, + displayName: { + type: "string", + maxGraphemes: 64, + maxLength: 640, + }, + description: { + type: "string", + maxGraphemes: 256, + maxLength: 2560, + }, + avatar: { + type: "string", + format: "uri", + }, + associated: { + type: "ref", + ref: "lex:so.sprk.actor.defs#profileAssociated", + }, + indexedAt: { + type: "string", + format: "datetime", + }, + createdAt: { + type: "string", + format: "datetime", + }, + viewer: { + type: "ref", + ref: "lex:so.sprk.actor.defs#viewerState", + }, + labels: { + type: "array", + items: { + type: "ref", + ref: "lex:com.atproto.label.defs#label", + }, + }, + }, + }, + profileViewDetailed: { + type: "object", + required: ["did", "handle"], + properties: { + did: { + type: "string", + format: "did", + }, + handle: { + type: "string", + format: "handle", + }, + displayName: { + type: "string", + maxGraphemes: 64, + maxLength: 640, + }, + description: { + type: "string", + maxGraphemes: 256, + maxLength: 2560, + }, + avatar: { + type: "string", + format: "uri", + }, + banner: { + type: "string", + format: "uri", + }, + followersCount: { + type: "integer", + }, + followsCount: { + type: "integer", + }, + postsCount: { + type: "integer", + }, + associated: { + type: "ref", + ref: "lex:so.sprk.actor.defs#profileAssociated", + }, + joinedViaStarterPack: { + type: "ref", + ref: "lex:so.sprk.graph.defs#starterPackViewBasic", + }, + indexedAt: { + type: "string", + format: "datetime", + }, + createdAt: { + type: "string", + format: "datetime", + }, + viewer: { + type: "ref", + ref: "lex:so.sprk.actor.defs#viewerState", + }, + labels: { + type: "array", + items: { + type: "ref", + ref: "lex:com.atproto.label.defs#label", + }, + }, + pinnedPost: { + type: "ref", + ref: "lex:com.atproto.repo.strongRef", + }, + }, + }, + profileAssociated: { + type: "object", + properties: { + lists: { + type: "integer", + }, + feedgens: { + type: "integer", + }, + starterPacks: { + type: "integer", + }, + labeler: { + type: "boolean", + }, + chat: { + type: "ref", + ref: "lex:so.sprk.actor.defs#profileAssociatedChat", + }, + }, + }, + profileAssociatedChat: { + type: "object", + required: ["allowIncoming"], + properties: { + allowIncoming: { + type: "string", + knownValues: ["all", "none", "following"], + }, + }, + }, + viewerState: { + type: "object", + description: + "Metadata about the requesting account's relationship with the subject account. Only has meaningful content for authed requests.", + properties: { + muted: { + type: "boolean", + }, + mutedByList: { + type: "ref", + ref: "lex:so.sprk.graph.defs#listViewBasic", + }, + blockedBy: { + type: "boolean", + }, + blocking: { + type: "string", + format: "at-uri", + }, + blockingByList: { + type: "ref", + ref: "lex:so.sprk.graph.defs#listViewBasic", + }, + following: { + type: "string", + format: "at-uri", + }, + followedBy: { + type: "string", + format: "at-uri", + }, + knownFollowers: { + type: "ref", + ref: "lex:so.sprk.actor.defs#knownFollowers", + }, + }, + }, + knownFollowers: { + type: "object", + description: "The subject's followers whom you also follow", + required: ["count", "followers"], + properties: { + count: { + type: "integer", + }, + followers: { + type: "array", + minLength: 0, + maxLength: 5, + items: { + type: "ref", + ref: "lex:so.sprk.actor.defs#profileViewBasic", + }, + }, + }, + }, + preferences: { + type: "array", + items: { + type: "union", + refs: [ + "lex:so.sprk.actor.defs#adultContentPref", + "lex:so.sprk.actor.defs#contentLabelPref", + "lex:so.sprk.actor.defs#savedFeedsPref", + "lex:so.sprk.actor.defs#savedFeedsPrefV2", + "lex:so.sprk.actor.defs#personalDetailsPref", + "lex:so.sprk.actor.defs#feedViewPref", + "lex:so.sprk.actor.defs#threadViewPref", + "lex:so.sprk.actor.defs#interestsPref", + "lex:so.sprk.actor.defs#mutedWordsPref", + "lex:so.sprk.actor.defs#hiddenPostsPref", + "lex:so.sprk.actor.defs#labelersPref", + "lex:so.sprk.actor.defs#postInteractionSettingsPref", + ], + }, + }, + adultContentPref: { + type: "object", + required: ["enabled"], + properties: { + enabled: { + type: "boolean", + default: false, + }, + }, + }, + contentLabelPref: { + type: "object", + required: ["label", "visibility"], + properties: { + labelerDid: { + type: "string", + description: + "Which labeler does this preference apply to? If undefined, applies globally.", + format: "did", + }, + label: { + type: "string", + }, + visibility: { + type: "string", + knownValues: ["ignore", "show", "warn", "hide"], + }, + }, + }, + savedFeed: { + type: "object", + required: ["id", "type", "value", "pinned"], + properties: { + id: { + type: "string", + }, + type: { + type: "string", + knownValues: ["feed", "list", "timeline"], + }, + value: { + type: "string", + }, + pinned: { + type: "boolean", + }, + }, + }, + savedFeedsPrefV2: { + type: "object", + required: ["items"], + properties: { + items: { + type: "array", + items: { + type: "ref", + ref: "lex:so.sprk.actor.defs#savedFeed", + }, + }, + }, + }, + savedFeedsPref: { + type: "object", + required: ["pinned", "saved"], + properties: { + pinned: { + type: "array", + items: { + type: "string", + format: "at-uri", + }, + }, + saved: { + type: "array", + items: { + type: "string", + format: "at-uri", + }, + }, + timelineIndex: { + type: "integer", + }, + }, + }, + personalDetailsPref: { + type: "object", + properties: { + birthDate: { + type: "string", + format: "datetime", + description: "The birth date of account owner.", + }, + }, + }, + feedViewPref: { + type: "object", + required: ["feed"], + properties: { + feed: { + type: "string", + description: + "The URI of the feed, or an identifier which describes the feed.", + }, + hideReplies: { + type: "boolean", + description: "Hide replies in the feed.", + }, + hideRepliesByUnfollowed: { + type: "boolean", + description: + "Hide replies in the feed if they are not by followed users.", + default: true, + }, + hideRepliesByLikeCount: { + type: "integer", + description: + "Hide replies in the feed if they do not have this number of likes.", + }, + hideRepliesByLookCount: { + type: "integer", + description: + "Hide replies in the feed if they do not have this number of looks.", + }, + hideReposts: { + type: "boolean", + description: "Hide reposts in the feed.", + }, + hideQuotePosts: { + type: "boolean", + description: "Hide quote posts in the feed.", + }, + }, + }, + threadViewPref: { + type: "object", + properties: { + sort: { + type: "string", + description: "Sorting mode for threads.", + knownValues: [ + "oldest", + "newest", + "most-likes", + "most-looks", + "random", + "hotness", + ], + }, + prioritizeFollowedUsers: { + type: "boolean", + description: "Show followed users at the top of all replies.", + }, + }, + }, + interestsPref: { + type: "object", + required: ["tags"], + properties: { + tags: { + type: "array", + maxLength: 100, + items: { + type: "string", + maxLength: 640, + maxGraphemes: 64, + }, + description: + "A list of tags which describe the account owner's interests gathered during onboarding.", + }, + }, + }, + mutedWordTarget: { + type: "string", + knownValues: ["content", "tag"], + maxLength: 640, + maxGraphemes: 64, + }, + mutedWord: { + type: "object", + description: "A word that the account owner has muted.", + required: ["value", "targets"], + properties: { + id: { + type: "string", + }, + value: { + type: "string", + description: "The muted word itself.", + maxLength: 10000, + maxGraphemes: 1000, + }, + targets: { + type: "array", + description: "The intended targets of the muted word.", + items: { + type: "ref", + ref: "lex:so.sprk.actor.defs#mutedWordTarget", + }, + }, + actorTarget: { + type: "string", + description: + "Groups of users to apply the muted word to. If undefined, applies to all users.", + knownValues: ["all", "exclude-following"], + default: "all", + }, + expiresAt: { + type: "string", + format: "datetime", + description: + "The date and time at which the muted word will expire and no longer be applied.", + }, + }, + }, + mutedWordsPref: { + type: "object", + required: ["items"], + properties: { + items: { + type: "array", + items: { + type: "ref", + ref: "lex:so.sprk.actor.defs#mutedWord", + }, + description: "A list of words the account owner has muted.", + }, + }, + }, + hiddenPostsPref: { + type: "object", + required: ["items"], + properties: { + items: { + type: "array", + items: { + type: "string", + format: "at-uri", + }, + description: + "A list of URIs of posts the account owner has hidden.", + }, + }, + }, + labelersPref: { + type: "object", + required: ["labelers"], + properties: { + labelers: { + type: "array", + items: { + type: "ref", + ref: "lex:so.sprk.actor.defs#labelerPrefItem", + }, + }, + }, + }, + labelerPrefItem: { + type: "object", + required: ["did"], + properties: { + did: { + type: "string", + format: "did", + }, + }, + }, + postInteractionSettingsPref: { + type: "object", + description: + "Default post interaction settings for the account. These values should be applied as default values when creating new posts. These refs should mirror the threadgate and postgate records exactly.", + required: [], + properties: { + threadgateAllowRules: { + description: + "Matches threadgate record. List of rules defining who can reply to this users posts. If value is an empty array, no one can reply. If value is undefined, anyone can reply.", + type: "array", + maxLength: 5, + items: { + type: "union", + refs: [ + "lex:so.sprk.feed.threadgate#mentionRule", + "lex:so.sprk.feed.threadgate#followerRule", + "lex:so.sprk.feed.threadgate#followingRule", + "lex:so.sprk.feed.threadgate#listRule", + ], + }, + }, + }, + }, + }, + }, + SoSprkActorGetPreferences: { + lexicon: 1, + id: "so.sprk.actor.getPreferences", + defs: { + main: { + type: "query", + description: + "Get private preferences attached to the current account. Expected use is synchronization between multiple devices, and import/export during account migration. Requires auth.", + parameters: { + type: "params", + properties: {}, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + properties: { + followMode: { + type: "string", + knownValues: ["bsky", "sprk"], + }, + }, + }, + }, + }, + }, + }, + SoSprkActorGetProfile: { + lexicon: 1, + id: "so.sprk.actor.getProfile", + defs: { + main: { + type: "query", + description: + "Get detailed profile view of an actor. Does not require auth, but contains relevant metadata with auth.", + parameters: { + type: "params", + required: ["actor"], + properties: { + actor: { + type: "string", + format: "at-identifier", + description: "Handle or DID of account to fetch profile of.", + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "ref", + ref: "lex:so.sprk.actor.defs#profileViewDetailed", + }, + }, + }, + }, + }, + SoSprkActorGetProfiles: { + lexicon: 1, + id: "so.sprk.actor.getProfiles", + defs: { + main: { + type: "query", + description: "Get detailed profile views of multiple actors.", + parameters: { + type: "params", + required: ["actors"], + properties: { + actors: { + type: "array", + items: { + type: "string", + format: "at-identifier", + }, + maxLength: 25, + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["profiles"], + properties: { + profiles: { + type: "array", + items: { + type: "ref", + ref: "lex:so.sprk.actor.defs#profileViewDetailed", + }, + }, + }, + }, + }, + }, + }, + }, + SoSprkActorGetSuggestions: { + lexicon: 1, + id: "so.sprk.actor.getSuggestions", + defs: { + main: { + type: "query", + description: + "Get a list of suggested actors. Expected use is discovery of accounts to follow during new account onboarding.", + parameters: { + type: "params", + properties: { + limit: { + type: "integer", + minimum: 1, + maximum: 100, + default: 50, + }, + cursor: { + type: "string", + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["actors"], + properties: { + cursor: { + type: "string", + }, + actors: { + type: "array", + items: { + type: "ref", + ref: "lex:so.sprk.actor.defs#profileView", + }, + }, + recId: { + type: "integer", + description: + "Snowflake for this recommendation, use when submitting recommendation events.", + }, + }, + }, + }, + }, + }, + }, + SoSprkActorProfile: { + lexicon: 1, + id: "so.sprk.actor.profile", + defs: { + main: { + type: "record", + description: "A declaration of a Spark account profile.", + key: "literal:self", + record: { + type: "object", + properties: { + displayName: { + type: "string", + maxGraphemes: 64, + maxLength: 640, + }, + description: { + type: "string", + description: "Free-form profile description text.", + maxGraphemes: 256, + maxLength: 2560, + }, + avatar: { + type: "blob", + description: + "Small image to be displayed next to posts from account. AKA, 'profile picture'", + accept: ["image/png", "image/jpeg"], + maxSize: 5242880, + }, + banner: { + type: "blob", + description: + "Larger horizontal image to display behind profile view.", + accept: ["image/png", "image/jpeg"], + maxSize: 5242880, + }, + labels: { + type: "union", + description: + "Self-label values, specific to the Spark applications, on the overall account.", + refs: ["lex:com.atproto.label.defs#selfLabels"], + }, + joinedViaStarterPack: { + type: "ref", + ref: "lex:com.atproto.repo.strongRef", + }, + pinnedPost: { + type: "ref", + ref: "lex:com.atproto.repo.strongRef", + }, + createdAt: { + type: "string", + format: "datetime", + }, + }, + }, + }, + }, + }, + SoSprkActorPutPreferences: { + lexicon: 1, + id: "so.sprk.actor.putPreferences", + defs: { + main: { + type: "procedure", + description: "Set the private preferences attached to the account.", + input: { + encoding: "application/json", + schema: { + type: "object", + properties: { + followMode: { + type: "string", + knownValues: ["bsky", "sprk"], + }, + }, + }, + }, + }, + }, + }, + SoSprkActorSearchActors: { + lexicon: 1, + id: "so.sprk.actor.searchActors", + defs: { + main: { + type: "query", + description: + "Find actors (profiles) matching search criteria. Does not require auth.", + parameters: { + type: "params", + properties: { + q: { + type: "string", + description: + "Search query string. Syntax, phrase, boolean, and faceting is unspecified, but Lucene query syntax is recommended.", + }, + limit: { + type: "integer", + minimum: 1, + maximum: 100, + default: 25, + }, + cursor: { + type: "string", + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["actors"], + properties: { + cursor: { + type: "string", + }, + actors: { + type: "array", + items: { + type: "ref", + ref: "lex:so.sprk.actor.defs#profileView", + }, + }, + }, + }, + }, + }, + }, + }, + SoSprkActorSearchActorsTypeahead: { + lexicon: 1, + id: "so.sprk.actor.searchActorsTypeahead", + defs: { + main: { + type: "query", + description: + "Find actor suggestions for a prefix search term. Expected use is for auto-completion during text field entry. Does not require auth.", + parameters: { + type: "params", + properties: { + q: { + type: "string", + description: "Search query prefix; not a full query string.", + }, + limit: { + type: "integer", + minimum: 1, + maximum: 100, + default: 10, + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["actors"], + properties: { + actors: { + type: "array", + items: { + type: "ref", + ref: "lex:so.sprk.actor.defs#profileViewBasic", + }, + }, + }, + }, + }, + }, + }, + }, + SoSprkEmbedDefs: { + lexicon: 1, + id: "so.sprk.embed.defs", + defs: { + aspectRatio: { + type: "object", + description: + "width:height represents an aspect ratio. It may be approximate, and may not correspond to absolute dimensions in any given unit.", + required: ["width", "height"], + properties: { + width: { + type: "integer", + minimum: 1, + }, + height: { + type: "integer", + minimum: 1, + }, + }, + }, + }, + }, + SoSprkEmbedImages: { + lexicon: 1, + id: "so.sprk.embed.images", + description: "A set of images embedded in a Spark record (eg, a post).", + defs: { + main: { + type: "object", + required: ["images"], + properties: { + images: { + type: "array", + items: { + type: "ref", + ref: "lex:so.sprk.embed.images#image", + }, + maxLength: 12, + }, + }, + }, + image: { + type: "object", + required: ["image", "alt"], + properties: { + image: { + type: "blob", + accept: ["image/*"], + maxSize: 5242880, + }, + alt: { + type: "string", + description: + "Alt text description of the image, for accessibility.", + }, + aspectRatio: { + type: "ref", + ref: "lex:so.sprk.embed.defs#aspectRatio", + }, + }, + }, + view: { + type: "object", + required: ["images"], + properties: { + images: { + type: "array", + items: { + type: "ref", + ref: "lex:so.sprk.embed.images#viewImage", + }, + maxLength: 4, + }, + }, + }, + viewImage: { + type: "object", + required: ["thumb", "fullsize", "alt"], + properties: { + thumb: { + type: "string", + format: "uri", + description: + "Fully-qualified URL where a thumbnail of the image can be fetched. For example, CDN location provided by the App View.", + }, + fullsize: { + type: "string", + format: "uri", + description: + "Fully-qualified URL where a large version of the image can be fetched. May or may not be the exact original blob. For example, CDN location provided by the App View.", + }, + alt: { + type: "string", + description: + "Alt text description of the image, for accessibility.", + }, + aspectRatio: { + type: "ref", + ref: "lex:so.sprk.embed.defs#aspectRatio", + }, + }, + }, + }, + }, + SoSprkEmbedVideo: { + lexicon: 1, + id: "so.sprk.embed.video", + description: "A video embedded in a Spark record (eg, a post).", + defs: { + main: { + type: "object", + required: ["video"], + properties: { + video: { + type: "blob", + accept: ["video/mp4"], + maxSize: 314572800, + }, + captions: { + type: "array", + items: { + type: "ref", + ref: "lex:so.sprk.embed.video#caption", + }, + maxLength: 20, + }, + alt: { + type: "string", + description: + "Alt text description of the video, for accessibility.", + maxGraphemes: 1000, + maxLength: 10000, + }, + aspectRatio: { + type: "ref", + ref: "lex:so.sprk.embed.defs#aspectRatio", + }, + }, + }, + caption: { + type: "object", + required: ["lang", "file"], + properties: { + lang: { + type: "string", + format: "language", + }, + file: { + type: "blob", + accept: ["text/vtt"], + maxSize: 20000, + }, + }, + }, + view: { + type: "object", + required: ["cid", "playlist"], + properties: { + cid: { + type: "string", + format: "cid", + }, + playlist: { + type: "string", + format: "uri", + }, + thumbnail: { + type: "string", + format: "uri", + }, + alt: { + type: "string", + maxGraphemes: 1000, + maxLength: 10000, + }, + aspectRatio: { + type: "ref", + ref: "lex:so.sprk.embed.defs#aspectRatio", + }, + }, + }, + }, + }, + SoSprkFeedDefs: { + lexicon: 1, + id: "so.sprk.feed.defs", + defs: { + postView: { + type: "object", + required: ["uri", "cid", "author", "record", "indexedAt"], + properties: { + uri: { + type: "string", + format: "at-uri", + }, + cid: { + type: "string", + format: "cid", + }, + author: { + type: "ref", + ref: "lex:so.sprk.actor.defs#profileViewBasic", + }, + record: { + type: "unknown", + }, + embed: { + type: "union", + refs: [ + "lex:so.sprk.embed.images#view", + "lex:so.sprk.embed.video#view", + ], + }, + sound: { + type: "ref", + ref: "lex:so.sprk.feed.defs#soundView", + }, + replyCount: { + type: "integer", + }, + repostCount: { + type: "integer", + }, + likeCount: { + type: "integer", + }, + lookCount: { + type: "integer", + }, + indexedAt: { + type: "string", + format: "datetime", + }, + viewer: { + type: "ref", + ref: "lex:so.sprk.feed.defs#viewerState", + }, + labels: { + type: "array", + items: { + type: "ref", + ref: "lex:com.atproto.label.defs#label", + }, + }, + threadgate: { + type: "ref", + ref: "lex:so.sprk.feed.defs#threadgateView", + }, + }, + }, + soundView: { + type: "object", + required: ["uri", "cid", "author", "record", "indexedAt"], + properties: { + uri: { + type: "string", + format: "at-uri", + }, + cid: { + type: "string", + format: "cid", + }, + author: { + type: "ref", + ref: "lex:so.sprk.actor.defs#profileViewBasic", + }, + record: { + type: "unknown", + }, + useCount: { + type: "integer", + }, + likeCount: { + type: "integer", + }, + indexedAt: { + type: "string", + format: "datetime", + }, + labels: { + type: "array", + items: { + type: "ref", + ref: "lex:com.atproto.label.defs#label", + }, + }, + }, + }, + viewerState: { + type: "object", + description: + "Metadata about the requesting account's relationship with the subject content. Only has meaningful content for authed requests.", + properties: { + repost: { + type: "string", + format: "at-uri", + }, + like: { + type: "string", + format: "at-uri", + }, + look: { + type: "string", + format: "at-uri", + }, + threadMuted: { + type: "boolean", + }, + replyDisabled: { + type: "boolean", + }, + embeddingDisabled: { + type: "boolean", + }, + pinned: { + type: "boolean", + }, + }, + }, + threadContext: { + type: "object", + description: + "Metadata about this post within the context of the thread it is in.", + properties: { + rootAuthorLike: { + type: "string", + format: "at-uri", + }, + }, + }, + feedViewPost: { + type: "object", + required: ["post"], + properties: { + post: { + type: "ref", + ref: "lex:so.sprk.feed.defs#postView", + }, + reply: { + type: "ref", + ref: "lex:so.sprk.feed.defs#replyRef", + }, + reason: { + type: "union", + refs: [ + "lex:so.sprk.feed.defs#reasonRepost", + "lex:so.sprk.feed.defs#reasonPin", + ], + }, + feedContext: { + type: "string", + description: + "Context provided by feed generator that may be passed back alongside interactions.", + maxLength: 2000, + }, + }, + }, + replyRef: { + type: "object", + required: ["root", "parent"], + properties: { + root: { + type: "union", + refs: [ + "lex:so.sprk.feed.defs#postView", + "lex:so.sprk.feed.defs#notFoundPost", + "lex:so.sprk.feed.defs#blockedPost", + ], + }, + parent: { + type: "union", + refs: [ + "lex:so.sprk.feed.defs#postView", + "lex:so.sprk.feed.defs#notFoundPost", + "lex:so.sprk.feed.defs#blockedPost", + ], + }, + grandparentAuthor: { + type: "ref", + ref: "lex:so.sprk.actor.defs#profileViewBasic", + description: + "When parent is a reply to another post, this is the author of that post.", + }, + }, + }, + reasonRepost: { + type: "object", + required: ["by", "indexedAt"], + properties: { + by: { + type: "ref", + ref: "lex:so.sprk.actor.defs#profileViewBasic", + }, + indexedAt: { + type: "string", + format: "datetime", + }, + }, + }, + reasonPin: { + type: "object", + properties: {}, + }, + threadViewPost: { + type: "object", + required: ["post"], + properties: { + post: { + type: "ref", + ref: "lex:so.sprk.feed.defs#postView", + }, + parent: { + type: "union", + refs: [ + "lex:so.sprk.feed.defs#threadViewPost", + "lex:so.sprk.feed.defs#notFoundPost", + "lex:so.sprk.feed.defs#blockedPost", + ], + }, + replies: { + type: "array", + items: { + type: "union", + refs: [ + "lex:so.sprk.feed.defs#threadViewPost", + "lex:so.sprk.feed.defs#notFoundPost", + "lex:so.sprk.feed.defs#blockedPost", + ], + }, + }, + threadContext: { + type: "ref", + ref: "lex:so.sprk.feed.defs#threadContext", + }, + }, + }, + notFoundPost: { + type: "object", + required: ["uri", "notFound"], + properties: { + uri: { + type: "string", + format: "at-uri", + }, + notFound: { + type: "boolean", + const: true, + }, + }, + }, + blockedPost: { + type: "object", + required: ["uri", "blocked", "author"], + properties: { + uri: { + type: "string", + format: "at-uri", + }, + blocked: { + type: "boolean", + const: true, + }, + author: { + type: "ref", + ref: "lex:so.sprk.feed.defs#blockedAuthor", + }, + }, + }, + blockedAuthor: { + type: "object", + required: ["did"], + properties: { + did: { + type: "string", + format: "did", + }, + viewer: { + type: "ref", + ref: "lex:so.sprk.actor.defs#viewerState", + }, + }, + }, + generatorView: { + type: "object", + required: ["uri", "cid", "did", "creator", "displayName", "indexedAt"], + properties: { + uri: { + type: "string", + format: "at-uri", + }, + cid: { + type: "string", + format: "cid", + }, + did: { + type: "string", + format: "did", + }, + creator: { + type: "ref", + ref: "lex:so.sprk.actor.defs#profileView", + }, + displayName: { + type: "string", + }, + description: { + type: "string", + maxGraphemes: 300, + maxLength: 3000, + }, + descriptionFacets: { + type: "array", + items: { + type: "ref", + ref: "lex:so.sprk.richtext.facet", + }, + }, + avatar: { + type: "string", + format: "uri", + }, + likeCount: { + type: "integer", + minimum: 0, + }, + lookCount: { + type: "integer", + minimum: 0, + }, + acceptsInteractions: { + type: "boolean", + }, + labels: { + type: "array", + items: { + type: "ref", + ref: "lex:com.atproto.label.defs#label", + }, + }, + viewer: { + type: "ref", + ref: "lex:so.sprk.feed.defs#generatorViewerState", + }, + contentMode: { + type: "string", + knownValues: [ + "so.sprk.feed.defs#contentModeUnspecified", + "so.sprk.feed.defs#contentModeVideo", + ], + }, + indexedAt: { + type: "string", + format: "datetime", + }, + }, + }, + generatorViewerState: { + type: "object", + properties: { + like: { + type: "string", + format: "at-uri", + }, + look: { + type: "string", + format: "at-uri", + }, + }, + }, + skeletonFeedPost: { + type: "object", + required: ["post"], + properties: { + post: { + type: "string", + format: "at-uri", + }, + reason: { + type: "union", + refs: [ + "lex:so.sprk.feed.defs#skeletonReasonRepost", + "lex:so.sprk.feed.defs#skeletonReasonPin", + ], + }, + feedContext: { + type: "string", + description: + "Context that will be passed through to client and may be passed to feed generator back alongside interactions.", + maxLength: 2000, + }, + }, + }, + skeletonReasonRepost: { + type: "object", + required: ["repost"], + properties: { + repost: { + type: "string", + format: "at-uri", + }, + }, + }, + skeletonReasonPin: { + type: "object", + properties: {}, + }, + threadgateView: { + type: "object", + properties: { + uri: { + type: "string", + format: "at-uri", + }, + cid: { + type: "string", + format: "cid", + }, + record: { + type: "unknown", + }, + lists: { + type: "array", + items: { + type: "ref", + ref: "lex:so.sprk.graph.defs#listViewBasic", + }, + }, + }, + }, + interaction: { + type: "object", + properties: { + item: { + type: "string", + format: "at-uri", + }, + event: { + type: "string", + knownValues: [ + "so.sprk.feed.defs#requestLess", + "so.sprk.feed.defs#requestMore", + "so.sprk.feed.defs#clickthroughItem", + "so.sprk.feed.defs#clickthroughAuthor", + "so.sprk.feed.defs#clickthroughReposter", + "so.sprk.feed.defs#clickthroughEmbed", + "so.sprk.feed.defs#interactionSeen", + "so.sprk.feed.defs#interactionLike", + "so.sprk.feed.defs#interactionRepost", + "so.sprk.feed.defs#interactionReply", + "so.sprk.feed.defs#interactionQuote", + "so.sprk.feed.defs#interactionShare", + ], + }, + feedContext: { + type: "string", + description: + "Context on a feed item that was originally supplied by the feed generator on getFeedSkeleton.", + maxLength: 2000, + }, + }, + }, + requestLess: { + type: "token", + description: + "Request that less content like the given feed item be shown in the feed", + }, + requestMore: { + type: "token", + description: + "Request that more content like the given feed item be shown in the feed", + }, + clickthroughItem: { + type: "token", + description: "User clicked through to the feed item", + }, + clickthroughAuthor: { + type: "token", + description: "User clicked through to the author of the feed item", + }, + clickthroughReposter: { + type: "token", + description: "User clicked through to the reposter of the feed item", + }, + clickthroughEmbed: { + type: "token", + description: + "User clicked through to the embedded content of the feed item", + }, + contentModeUnspecified: { + type: "token", + description: "Declares the feed generator returns any types of posts.", + }, + contentModeVideo: { + type: "token", + description: + "Declares the feed generator returns posts containing so.sprk.embed.video embeds.", + }, + interactionSeen: { + type: "token", + description: "Feed item was seen by user", + }, + interactionLike: { + type: "token", + description: "User liked the feed item", + }, + interactionRepost: { + type: "token", + description: "User reposted the feed item", + }, + interactionReply: { + type: "token", + description: "User replied to the feed item", + }, + interactionQuote: { + type: "token", + description: "User quoted the feed item", + }, + interactionShare: { + type: "token", + description: "User shared the feed item", + }, + }, + }, + SoSprkFeedDescribeFeedGenerator: { + lexicon: 1, + id: "so.sprk.feed.describeFeedGenerator", + defs: { + main: { + type: "query", + description: + "Get information about a feed generator, including policies and offered feed URIs. Does not require auth; implemented by Feed Generator services (not App View).", + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["did", "feeds"], + properties: { + did: { + type: "string", + format: "did", + }, + feeds: { + type: "array", + items: { + type: "ref", + ref: "lex:so.sprk.feed.describeFeedGenerator#feed", + }, + }, + links: { + type: "ref", + ref: "lex:so.sprk.feed.describeFeedGenerator#links", + }, + }, + }, + }, + }, + feed: { + type: "object", + required: ["uri"], + properties: { + uri: { + type: "string", + format: "at-uri", + }, + }, + }, + links: { + type: "object", + properties: { + privacyPolicy: { + type: "string", + }, + termsOfService: { + type: "string", + }, + }, + }, + }, + }, + SoSprkFeedGenerator: { + lexicon: 1, + id: "so.sprk.feed.generator", + defs: { + main: { + type: "record", + description: + "Record declaring of the existence of a feed generator, and containing metadata about it. The record can exist in any repository.", + key: "any", + record: { + type: "object", + required: ["did", "displayName", "createdAt"], + properties: { + did: { + type: "string", + format: "did", + }, + displayName: { + type: "string", + maxGraphemes: 24, + maxLength: 240, + }, + description: { + type: "string", + maxGraphemes: 300, + maxLength: 3000, + }, + descriptionFacets: { + type: "array", + items: { + type: "ref", + ref: "lex:so.sprk.richtext.facet", + }, + }, + avatar: { + type: "blob", + accept: ["image/png", "image/jpeg"], + maxSize: 1000000, + }, + acceptsInteractions: { + type: "boolean", + description: + "Declaration that a feed accepts feedback interactions from a client through so.sprk.feed.sendInteractions", + }, + labels: { + type: "union", + description: "Self-label values", + refs: ["lex:com.atproto.label.defs#selfLabels"], + }, + contentMode: { + type: "string", + knownValues: [ + "so.sprk.feed.defs#contentModeUnspecified", + "so.sprk.feed.defs#contentModeVideo", + ], + }, + createdAt: { + type: "string", + format: "datetime", + }, + }, + }, + }, + }, + }, + SoSprkFeedGetActorFeeds: { + lexicon: 1, + id: "so.sprk.feed.getActorFeeds", + defs: { + main: { + type: "query", + description: + "Get a list of feeds (feed generator records) created by the actor (in the actor's repo).", + parameters: { + type: "params", + required: ["actor"], + properties: { + actor: { + type: "string", + format: "at-identifier", + }, + limit: { + type: "integer", + minimum: 1, + maximum: 100, + default: 50, + }, + cursor: { + type: "string", + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["feeds"], + properties: { + cursor: { + type: "string", + }, + feeds: { + type: "array", + items: { + type: "ref", + ref: "lex:so.sprk.feed.defs#generatorView", + }, + }, + }, + }, + }, + }, + }, + }, + SoSprkFeedGetActorLikes: { + lexicon: 1, + id: "so.sprk.feed.getActorLikes", + defs: { + main: { + type: "query", + description: + "Get a list of posts liked by an actor. Requires auth, actor must be the requesting account.", + parameters: { + type: "params", + required: ["actor"], + properties: { + actor: { + type: "string", + format: "at-identifier", + }, + limit: { + type: "integer", + minimum: 1, + maximum: 100, + default: 50, + }, + cursor: { + type: "string", + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["feed"], + properties: { + cursor: { + type: "string", + }, + feed: { + type: "array", + items: { + type: "ref", + ref: "lex:so.sprk.feed.defs#feedViewPost", + }, + }, + }, + }, + }, + errors: [ + { + name: "BlockedActor", + }, + { + name: "BlockedByActor", + }, + ], + }, + }, + }, + SoSprkFeedGetActorLooks: { + lexicon: 1, + id: "so.sprk.feed.getActorLooks", + defs: { + main: { + type: "query", + description: + "Get a list of posts looked by an actor. Requires auth, actor must be the requesting account.", + parameters: { + type: "params", + required: ["actor"], + properties: { + actor: { + type: "string", + format: "at-identifier", + }, + limit: { + type: "integer", + minimum: 1, + maximum: 100, + default: 50, + }, + cursor: { + type: "string", + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["feed"], + properties: { + cursor: { + type: "string", + }, + feed: { + type: "array", + items: { + type: "ref", + ref: "lex:so.sprk.feed.defs#feedViewPost", + }, + }, + }, + }, + }, + errors: [ + { + name: "BlockedActor", + }, + { + name: "BlockedByActor", + }, + ], + }, + }, + }, + SoSprkFeedGetAuthorFeed: { + lexicon: 1, + id: "so.sprk.feed.getAuthorFeed", + defs: { + main: { + type: "query", + description: + "Get a view of an actor's 'author feed' (post and reposts by the author). Does not require auth.", + parameters: { + type: "params", + required: ["actor"], + properties: { + actor: { + type: "string", + format: "at-identifier", + }, + limit: { + type: "integer", + minimum: 1, + maximum: 100, + default: 50, + }, + cursor: { + type: "string", + }, + filter: { + type: "string", + description: + "Combinations of post/repost types to include in response.", + knownValues: [ + "posts_with_replies", + "posts_no_replies", + "posts_with_media", + "posts_and_author_threads", + "posts_with_video", + ], + default: "posts_with_replies", + }, + includePins: { + type: "boolean", + default: false, + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["feed"], + properties: { + cursor: { + type: "string", + }, + feed: { + type: "array", + items: { + type: "ref", + ref: "lex:so.sprk.feed.defs#feedViewPost", + }, + }, + }, + }, + }, + errors: [ + { + name: "BlockedActor", + }, + { + name: "BlockedByActor", + }, + ], + }, + }, + }, + SoSprkFeedGetFeedGenerator: { + lexicon: 1, + id: "so.sprk.feed.getFeedGenerator", + defs: { + main: { + type: "query", + description: + "Get information about a feed generator. Implemented by AppView.", + parameters: { + type: "params", + required: ["feed"], + properties: { + feed: { + type: "string", + format: "at-uri", + description: "AT-URI of the feed generator record.", + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["view", "isOnline", "isValid"], + properties: { + view: { + type: "ref", + ref: "lex:so.sprk.feed.defs#generatorView", + }, + isOnline: { + type: "boolean", + description: + "Indicates whether the feed generator service has been online recently, or else seems to be inactive.", + }, + isValid: { + type: "boolean", + description: + "Indicates whether the feed generator service is compatible with the record declaration.", + }, + }, + }, + }, + }, + }, + }, + SoSprkFeedGetFeedGenerators: { + lexicon: 1, + id: "so.sprk.feed.getFeedGenerators", + defs: { + main: { + type: "query", + description: "Get information about a list of feed generators.", + parameters: { + type: "params", + required: ["feeds"], + properties: { + feeds: { + type: "array", + items: { + type: "string", + format: "at-uri", + }, + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["feeds"], + properties: { + feeds: { + type: "array", + items: { + type: "ref", + ref: "lex:so.sprk.feed.defs#generatorView", + }, + }, + }, + }, + }, + }, + }, + }, + SoSprkFeedGetFeed: { + lexicon: 1, + id: "so.sprk.feed.getFeed", + defs: { + main: { + type: "query", + description: + "Get a hydrated feed from an actor's selected feed generator. Implemented by App View.", + parameters: { + type: "params", + required: ["feed"], + properties: { + feed: { + type: "string", + format: "at-uri", + }, + limit: { + type: "integer", + minimum: 1, + maximum: 100, + default: 50, + }, + cursor: { + type: "string", + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["feed"], + properties: { + cursor: { + type: "string", + }, + feed: { + type: "array", + items: { + type: "ref", + ref: "lex:so.sprk.feed.defs#feedViewPost", + }, + }, + }, + }, + }, + errors: [ + { + name: "UnknownFeed", + }, + ], + }, + }, + }, + SoSprkFeedGetFeedSkeleton: { + lexicon: 1, + id: "so.sprk.feed.getFeedSkeleton", + defs: { + main: { + type: "query", + description: + "Get a skeleton of a feed provided by a feed generator. Auth is optional, depending on provider requirements, and provides the DID of the requester. Implemented by Feed Generator Service.", + parameters: { + type: "params", + required: ["feed"], + properties: { + feed: { + type: "string", + format: "at-uri", + description: + "Reference to feed generator record describing the specific feed being requested.", + }, + limit: { + type: "integer", + minimum: 1, + maximum: 100, + default: 50, + }, + cursor: { + type: "string", + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["feed"], + properties: { + cursor: { + type: "string", + }, + feed: { + type: "array", + items: { + type: "ref", + ref: "lex:so.sprk.feed.defs#skeletonFeedPost", + }, + }, + }, + }, + }, + errors: [ + { + name: "UnknownFeed", + }, + ], + }, + }, + }, + SoSprkFeedGetLikes: { + lexicon: 1, + id: "so.sprk.feed.getLikes", + defs: { + main: { + type: "query", + description: + "Get like records which reference a subject (by AT-URI and CID).", + parameters: { + type: "params", + required: ["uri"], + properties: { + uri: { + type: "string", + format: "at-uri", + description: "AT-URI of the subject (eg, a post record).", + }, + cid: { + type: "string", + format: "cid", + description: + "CID of the subject record (aka, specific version of record), to filter likes.", + }, + limit: { + type: "integer", + minimum: 1, + maximum: 100, + default: 50, + }, + cursor: { + type: "string", + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["uri", "likes"], + properties: { + uri: { + type: "string", + format: "at-uri", + }, + cid: { + type: "string", + format: "cid", + }, + cursor: { + type: "string", + }, + likes: { + type: "array", + items: { + type: "ref", + ref: "lex:so.sprk.feed.getLikes#like", + }, + }, + }, + }, + }, + }, + like: { + type: "object", + required: ["indexedAt", "createdAt", "actor"], + properties: { + indexedAt: { + type: "string", + format: "datetime", + }, + createdAt: { + type: "string", + format: "datetime", + }, + actor: { + type: "ref", + ref: "lex:so.sprk.actor.defs#profileView", + }, + }, + }, + }, + }, + SoSprkFeedGetListFeed: { + lexicon: 1, + id: "so.sprk.feed.getListFeed", + defs: { + main: { + type: "query", + description: + "Get a feed of recent posts from a list (posts and reposts from any actors on the list). Does not require auth.", + parameters: { + type: "params", + required: ["list"], + properties: { + list: { + type: "string", + format: "at-uri", + description: "Reference (AT-URI) to the list record.", + }, + limit: { + type: "integer", + minimum: 1, + maximum: 100, + default: 50, + }, + cursor: { + type: "string", + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["feed"], + properties: { + cursor: { + type: "string", + }, + feed: { + type: "array", + items: { + type: "ref", + ref: "lex:so.sprk.feed.defs#feedViewPost", + }, + }, + }, + }, + }, + errors: [ + { + name: "UnknownList", + }, + ], + }, + }, + }, + SoSprkFeedGetLooks: { + lexicon: 1, + id: "so.sprk.feed.getLooks", + defs: { + main: { + type: "query", + description: + "Get look records which reference a subject (by AT-URI and CID).", + parameters: { + type: "params", + required: ["uri"], + properties: { + uri: { + type: "string", + format: "at-uri", + description: "AT-URI of the subject (eg, a post record).", + }, + cid: { + type: "string", + format: "cid", + description: + "CID of the subject record (aka, specific version of record), to filter looks.", + }, + limit: { + type: "integer", + minimum: 1, + maximum: 100, + default: 50, + }, + cursor: { + type: "string", + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["uri", "looks"], + properties: { + uri: { + type: "string", + format: "at-uri", + }, + cid: { + type: "string", + format: "cid", + }, + cursor: { + type: "string", + }, + looks: { + type: "array", + items: { + type: "ref", + ref: "lex:so.sprk.feed.getLooks#look", + }, + }, + }, + }, + }, + }, + look: { + type: "object", + required: ["indexedAt", "createdAt", "actor"], + properties: { + indexedAt: { + type: "string", + format: "datetime", + }, + createdAt: { + type: "string", + format: "datetime", + }, + actor: { + type: "ref", + ref: "lex:so.sprk.actor.defs#profileView", + }, + }, + }, + }, + }, + SoSprkFeedGetPosts: { + lexicon: 1, + id: "so.sprk.feed.getPosts", + defs: { + main: { + type: "query", + description: + "Gets post views for a specified list of posts (by AT-URI). This is sometimes referred to as 'hydrating' a 'feed skeleton'.", + parameters: { + type: "params", + required: ["uris"], + properties: { + uris: { + type: "array", + description: "List of post AT-URIs to return hydrated views for.", + items: { + type: "string", + format: "at-uri", + }, + maxLength: 25, + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["posts"], + properties: { + posts: { + type: "array", + items: { + type: "ref", + ref: "lex:so.sprk.feed.defs#postView", + }, + }, + }, + }, + }, + }, + }, + }, + SoSprkFeedGetPostThread: { + lexicon: 1, + id: "so.sprk.feed.getPostThread", + defs: { + main: { + type: "query", + description: + "Get posts in a thread. Does not require auth, but additional metadata and filtering will be applied for authed requests.", + parameters: { + type: "params", + required: ["uri"], + properties: { + uri: { + type: "string", + format: "at-uri", + description: "Reference (AT-URI) to post record.", + }, + depth: { + type: "integer", + description: + "How many levels of reply depth should be included in response.", + default: 6, + minimum: 0, + maximum: 1000, + }, + parentHeight: { + type: "integer", + description: + "How many levels of parent (and grandparent, etc) post to include.", + default: 80, + minimum: 0, + maximum: 1000, + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["thread"], + properties: { + thread: { + type: "union", + refs: [ + "lex:so.sprk.feed.defs#threadViewPost", + "lex:so.sprk.feed.defs#notFoundPost", + "lex:so.sprk.feed.defs#blockedPost", + ], + }, + threadgate: { + type: "ref", + ref: "lex:so.sprk.feed.defs#threadgateView", + }, + }, + }, + }, + errors: [ + { + name: "NotFound", + }, + ], + }, + }, + }, + SoSprkFeedGetQuotes: { + lexicon: 1, + id: "so.sprk.feed.getQuotes", + defs: { + main: { + type: "query", + description: "Get a list of quotes for a given post.", + parameters: { + type: "params", + required: ["uri"], + properties: { + uri: { + type: "string", + format: "at-uri", + description: "Reference (AT-URI) of post record", + }, + cid: { + type: "string", + format: "cid", + description: + "If supplied, filters to quotes of specific version (by CID) of the post record.", + }, + limit: { + type: "integer", + minimum: 1, + maximum: 100, + default: 50, + }, + cursor: { + type: "string", + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["uri", "posts"], + properties: { + uri: { + type: "string", + format: "at-uri", + }, + cid: { + type: "string", + format: "cid", + }, + cursor: { + type: "string", + }, + posts: { + type: "array", + items: { + type: "ref", + ref: "lex:so.sprk.feed.defs#postView", + }, + }, + }, + }, + }, + }, + }, + }, + SoSprkFeedGetRepostedBy: { + lexicon: 1, + id: "so.sprk.feed.getRepostedBy", + defs: { + main: { + type: "query", + description: "Get a list of reposts for a given post.", + parameters: { + type: "params", + required: ["uri"], + properties: { + uri: { + type: "string", + format: "at-uri", + description: "Reference (AT-URI) of post record", + }, + cid: { + type: "string", + format: "cid", + description: + "If supplied, filters to reposts of specific version (by CID) of the post record.", + }, + limit: { + type: "integer", + minimum: 1, + maximum: 100, + default: 50, + }, + cursor: { + type: "string", + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["uri", "repostedBy"], + properties: { + uri: { + type: "string", + format: "at-uri", + }, + cid: { + type: "string", + format: "cid", + }, + cursor: { + type: "string", + }, + repostedBy: { + type: "array", + items: { + type: "ref", + ref: "lex:so.sprk.actor.defs#profileView", + }, + }, + }, + }, + }, + }, + }, + }, + SoSprkFeedGetSuggestedFeeds: { + lexicon: 1, + id: "so.sprk.feed.getSuggestedFeeds", + defs: { + main: { + type: "query", + description: + "Get a list of suggested feeds (feed generators) for the requesting account.", + parameters: { + type: "params", + properties: { + limit: { + type: "integer", + minimum: 1, + maximum: 100, + default: 50, + }, + cursor: { + type: "string", + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["feeds"], + properties: { + cursor: { + type: "string", + }, + feeds: { + type: "array", + items: { + type: "ref", + ref: "lex:so.sprk.feed.defs#generatorView", + }, + }, + }, + }, + }, + }, + }, + }, + SoSprkFeedGetTimeline: { + lexicon: 1, + id: "so.sprk.feed.getTimeline", + defs: { + main: { + type: "query", + description: + "Get a view of the requesting account's home timeline. This is expected to be some form of reverse-chronological feed.", + parameters: { + type: "params", + properties: { + algorithm: { + type: "string", + description: + "Variant 'algorithm' for timeline. Implementation-specific. NOTE: most feed flexibility has been moved to feed generator mechanism.", + }, + limit: { + type: "integer", + minimum: 1, + maximum: 100, + default: 50, + }, + cursor: { + type: "string", + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["feed"], + properties: { + cursor: { + type: "string", + }, + feed: { + type: "array", + items: { + type: "ref", + ref: "lex:so.sprk.feed.defs#feedViewPost", + }, + }, + }, + }, + }, + }, + }, + }, + SoSprkFeedLike: { + lexicon: 1, + id: "so.sprk.feed.like", + defs: { + main: { + type: "record", + description: + "Record declaring a 'like' of a piece of subject content. Duplicate likes from the same author to the same subject will be ignored by the AppView.", + key: "tid", + record: { + type: "object", + required: ["subject", "createdAt"], + properties: { + subject: { + type: "ref", + ref: "lex:com.atproto.repo.strongRef", + }, + createdAt: { + type: "string", + format: "datetime", + }, + }, + }, + }, + }, + }, + SoSprkFeedLook: { + lexicon: 1, + id: "so.sprk.feed.look", + defs: { + main: { + type: "record", + description: + "Record declaring a 'look' of a piece of subject content. Equivalent to a 'view'", + key: "tid", + record: { + type: "object", + required: ["subject", "createdAt"], + properties: { + subject: { + type: "ref", + ref: "lex:com.atproto.repo.strongRef", + }, + createdAt: { + type: "string", + format: "datetime", + }, + }, + }, + }, + }, + }, + SoSprkFeedPostgate: { + lexicon: 1, + id: "so.sprk.feed.postgate", + defs: { + main: { + type: "record", + key: "tid", + description: + "Record defining interaction rules for a post. The record key (rkey) of the postgate record must match the record key of the post, and that record must be in the same repository.", + record: { + type: "object", + required: ["post", "createdAt"], + properties: { + createdAt: { + type: "string", + format: "datetime", + }, + post: { + type: "string", + format: "at-uri", + description: "Reference (AT-URI) to the post record.", + }, + detachedEmbeddingUris: { + type: "array", + maxLength: 50, + items: { + type: "string", + format: "at-uri", + }, + description: + "List of AT-URIs embedding this post that the author has detached from.", + }, + embeddingRules: { + description: + "List of rules defining who can embed this post. If value is an empty array or is undefined, no particular rules apply and anyone can embed.", + type: "array", + maxLength: 5, + items: { + type: "union", + refs: ["lex:so.sprk.feed.postgate#disableRule"], + }, + }, + }, + }, + }, + disableRule: { + type: "object", + description: "Disables embedding of this post.", + properties: {}, + }, + }, + }, + SoSprkFeedPost: { + lexicon: 1, + id: "so.sprk.feed.post", + defs: { + main: { + type: "record", + description: "Record containing a Spark post.", + key: "tid", + record: { + type: "object", + required: ["createdAt"], + properties: { + text: { + type: "string", + maxLength: 3000, + maxGraphemes: 300, + description: "The post description.", + }, + facets: { + type: "array", + description: + "Annotations of text (mentions, URLs, hashtags, etc)", + items: { + type: "ref", + ref: "lex:so.sprk.richtext.facet", + }, + }, + reply: { + type: "ref", + ref: "lex:so.sprk.feed.post#replyRef", + }, + embed: { + type: "union", + refs: ["lex:so.sprk.embed.images", "lex:so.sprk.embed.video"], + }, + sound: { + type: "ref", + ref: "lex:com.atproto.repo.strongRef", + }, + langs: { + type: "array", + description: + "Indicates human language of post primary text content.", + maxLength: 3, + items: { + type: "string", + format: "language", + }, + }, + labels: { + type: "union", + description: + "Self-label values for this post. Effectively content warnings.", + refs: ["lex:com.atproto.label.defs#selfLabels"], + }, + tags: { + type: "array", + description: + "Additional hashtags, in addition to any included in post text and facets.", + maxLength: 8, + items: { + type: "string", + maxLength: 640, + maxGraphemes: 64, + }, + }, + createdAt: { + type: "string", + format: "datetime", + description: + "Client-declared timestamp when this post was originally created.", + }, + }, + }, + }, + replyRef: { + type: "object", + required: ["root", "parent"], + properties: { + root: { + type: "ref", + ref: "lex:com.atproto.repo.strongRef", + }, + parent: { + type: "ref", + ref: "lex:com.atproto.repo.strongRef", + }, + }, + }, + }, + }, + SoSprkFeedRepost: { + lexicon: 1, + id: "so.sprk.feed.repost", + defs: { + main: { + description: + "Record representing a 'repost' of an existing Spark post.", + type: "record", + key: "tid", + record: { + type: "object", + required: ["subject", "createdAt"], + properties: { + subject: { + type: "ref", + ref: "lex:com.atproto.repo.strongRef", + }, + createdAt: { + type: "string", + format: "datetime", + }, + }, + }, + }, + }, + }, + SoSprkFeedSearchPosts: { + lexicon: 1, + id: "so.sprk.feed.searchPosts", + defs: { + main: { + type: "query", + description: + "Find posts matching search criteria, returning views of those posts.", + parameters: { + type: "params", + required: ["q"], + properties: { + q: { + type: "string", + description: + "Search query string; syntax, phrase, boolean, and faceting is unspecified, but Lucene query syntax is recommended.", + }, + sort: { + type: "string", + knownValues: ["top", "latest"], + default: "latest", + description: "Specifies the ranking order of results.", + }, + since: { + type: "string", + description: + "Filter results for posts after the indicated datetime (inclusive). Expected to use 'sortAt' timestamp, which may not match 'createdAt'. Can be a datetime, or just an ISO date (YYYY-MM-DD).", + }, + until: { + type: "string", + description: + "Filter results for posts before the indicated datetime (not inclusive). Expected to use 'sortAt' timestamp, which may not match 'createdAt'. Can be a datetime, or just an ISO date (YYY-MM-DD).", + }, + mentions: { + type: "string", + format: "at-identifier", + description: + "Filter to posts which mention the given account. Handles are resolved to DID before query-time. Only matches rich-text facet mentions.", + }, + author: { + type: "string", + format: "at-identifier", + description: + "Filter to posts by the given account. Handles are resolved to DID before query-time.", + }, + lang: { + type: "string", + format: "language", + description: + "Filter to posts in the given language. Expected to be based on post language field, though server may override language detection.", + }, + domain: { + type: "string", + description: + "Filter to posts with URLs (facet links or embeds) linking to the given domain (hostname). Server may apply hostname normalization.", + }, + url: { + type: "string", + format: "uri", + description: + "Filter to posts with links (facet links or embeds) pointing to this URL. Server may apply URL normalization or fuzzy matching.", + }, + tag: { + type: "array", + items: { + type: "string", + maxLength: 640, + maxGraphemes: 64, + }, + description: + "Filter to posts with the given tag (hashtag), based on rich-text facet or tag field. Do not include the hash (#) prefix. Multiple tags can be specified, with 'AND' matching.", + }, + limit: { + type: "integer", + minimum: 1, + maximum: 100, + default: 25, + }, + cursor: { + type: "string", + description: + "Optional pagination mechanism; may not necessarily allow scrolling through entire result set.", + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["posts"], + properties: { + cursor: { + type: "string", + }, + hitsTotal: { + type: "integer", + description: + "Count of search hits. Optional, may be rounded/truncated, and may not be possible to paginate through all hits.", + }, + posts: { + type: "array", + items: { + type: "ref", + ref: "lex:so.sprk.feed.defs#postView", + }, + }, + }, + }, + }, + errors: [ + { + name: "BadQueryString", + }, + ], + }, + }, + }, + SoSprkFeedSendInteractions: { + lexicon: 1, + id: "so.sprk.feed.sendInteractions", + defs: { + main: { + type: "procedure", + description: + "Send information about interactions with feed items back to the feed generator that served them.", + input: { + encoding: "application/json", + schema: { + type: "object", + required: ["interactions"], + properties: { + interactions: { + type: "array", + items: { + type: "ref", + ref: "lex:so.sprk.feed.defs#interaction", + }, + }, + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + properties: {}, + }, + }, + }, + }, + }, + SoSprkFeedThreadgate: { + lexicon: 1, + id: "so.sprk.feed.threadgate", + defs: { + main: { + type: "record", + key: "tid", + description: + "Record defining interaction gating rules for a thread (aka, reply controls). The record key (rkey) of the threadgate record must match the record key of the thread's root post, and that record must be in the same repository.", + record: { + type: "object", + required: ["post", "createdAt"], + properties: { + post: { + type: "string", + format: "at-uri", + description: "Reference (AT-URI) to the post record.", + }, + allow: { + description: + "List of rules defining who can reply to this post. If value is an empty array, no one can reply. If value is undefined, anyone can reply.", + type: "array", + maxLength: 5, + items: { + type: "union", + refs: [ + "lex:so.sprk.feed.threadgate#mentionRule", + "lex:so.sprk.feed.threadgate#followerRule", + "lex:so.sprk.feed.threadgate#followingRule", + "lex:so.sprk.feed.threadgate#listRule", + ], + }, + }, + createdAt: { + type: "string", + format: "datetime", + }, + hiddenReplies: { + type: "array", + maxLength: 50, + items: { + type: "string", + format: "at-uri", + }, + description: "List of hidden reply URIs.", + }, + }, + }, + }, + mentionRule: { + type: "object", + description: "Allow replies from actors mentioned in your post.", + properties: {}, + }, + followerRule: { + type: "object", + description: "Allow replies from actors who follow you.", + properties: {}, + }, + followingRule: { + type: "object", + description: "Allow replies from actors you follow.", + properties: {}, + }, + listRule: { + type: "object", + description: "Allow replies from actors on a list.", + required: ["list"], + properties: { + list: { + type: "string", + format: "at-uri", + }, + }, + }, + }, + }, + SoSprkGraphBlock: { + lexicon: 1, + id: "so.sprk.graph.block", + defs: { + main: { + type: "record", + description: + "Record declaring a 'block' relationship against another account. NOTE: blocks are public in Spark; see blog posts for details.", + key: "tid", + record: { + type: "object", + required: ["subject", "createdAt"], + properties: { + subject: { + type: "string", + format: "did", + description: "DID of the account to be blocked.", + }, + createdAt: { + type: "string", + format: "datetime", + }, + }, + }, + }, + }, + }, + SoSprkGraphDefs: { + lexicon: 1, + id: "so.sprk.graph.defs", + defs: { + listViewBasic: { + type: "object", + required: ["uri", "cid", "name", "purpose"], + properties: { + uri: { + type: "string", + format: "at-uri", + }, + cid: { + type: "string", + format: "cid", + }, + name: { + type: "string", + maxLength: 64, + minLength: 1, + }, + purpose: { + type: "ref", + ref: "lex:so.sprk.graph.defs#listPurpose", + }, + avatar: { + type: "string", + format: "uri", + }, + listItemCount: { + type: "integer", + minimum: 0, + }, + labels: { + type: "array", + items: { + type: "ref", + ref: "lex:com.atproto.label.defs#label", + }, + }, + viewer: { + type: "ref", + ref: "lex:so.sprk.graph.defs#listViewerState", + }, + indexedAt: { + type: "string", + format: "datetime", + }, + }, + }, + listView: { + type: "object", + required: ["uri", "cid", "creator", "name", "purpose", "indexedAt"], + properties: { + uri: { + type: "string", + format: "at-uri", + }, + cid: { + type: "string", + format: "cid", + }, + creator: { + type: "ref", + ref: "lex:so.sprk.actor.defs#profileView", + }, + name: { + type: "string", + maxLength: 64, + minLength: 1, + }, + purpose: { + type: "ref", + ref: "lex:so.sprk.graph.defs#listPurpose", + }, + description: { + type: "string", + maxGraphemes: 300, + maxLength: 3000, + }, + descriptionFacets: { + type: "array", + items: { + type: "ref", + ref: "lex:so.sprk.richtext.facet", + }, + }, + avatar: { + type: "string", + format: "uri", + }, + listItemCount: { + type: "integer", + minimum: 0, + }, + labels: { + type: "array", + items: { + type: "ref", + ref: "lex:com.atproto.label.defs#label", + }, + }, + viewer: { + type: "ref", + ref: "lex:so.sprk.graph.defs#listViewerState", + }, + indexedAt: { + type: "string", + format: "datetime", + }, + }, + }, + listItemView: { + type: "object", + required: ["uri", "subject"], + properties: { + uri: { + type: "string", + format: "at-uri", + }, + subject: { + type: "ref", + ref: "lex:so.sprk.actor.defs#profileView", + }, + }, + }, + starterPackView: { + type: "object", + required: ["uri", "cid", "record", "creator", "indexedAt"], + properties: { + uri: { + type: "string", + format: "at-uri", + }, + cid: { + type: "string", + format: "cid", + }, + record: { + type: "unknown", + }, + creator: { + type: "ref", + ref: "lex:so.sprk.actor.defs#profileViewBasic", + }, + list: { + type: "ref", + ref: "lex:so.sprk.graph.defs#listViewBasic", + }, + listItemsSample: { + type: "array", + maxLength: 12, + items: { + type: "ref", + ref: "lex:so.sprk.graph.defs#listItemView", + }, + }, + feeds: { + type: "array", + maxLength: 3, + items: { + type: "ref", + ref: "lex:so.sprk.feed.defs#generatorView", + }, + }, + joinedWeekCount: { + type: "integer", + minimum: 0, + }, + joinedAllTimeCount: { + type: "integer", + minimum: 0, + }, + labels: { + type: "array", + items: { + type: "ref", + ref: "lex:com.atproto.label.defs#label", + }, + }, + indexedAt: { + type: "string", + format: "datetime", + }, + }, + }, + starterPackViewBasic: { + type: "object", + required: ["uri", "cid", "record", "creator", "indexedAt"], + properties: { + uri: { + type: "string", + format: "at-uri", + }, + cid: { + type: "string", + format: "cid", + }, + record: { + type: "unknown", + }, + creator: { + type: "ref", + ref: "lex:so.sprk.actor.defs#profileViewBasic", + }, + listItemCount: { + type: "integer", + minimum: 0, + }, + joinedWeekCount: { + type: "integer", + minimum: 0, + }, + joinedAllTimeCount: { + type: "integer", + minimum: 0, + }, + labels: { + type: "array", + items: { + type: "ref", + ref: "lex:com.atproto.label.defs#label", + }, + }, + indexedAt: { + type: "string", + format: "datetime", + }, + }, + }, + listPurpose: { + type: "string", + knownValues: [ + "so.sprk.graph.defs#modlist", + "so.sprk.graph.defs#curatelist", + "so.sprk.graph.defs#referencelist", + ], + }, + modlist: { + type: "token", + description: + "A list of actors to apply an aggregate moderation action (mute/block) on.", + }, + curatelist: { + type: "token", + description: + "A list of actors used for curation purposes such as list feeds or interaction gating.", + }, + referencelist: { + type: "token", + description: + "A list of actors used for only for reference purposes such as within a starter pack.", + }, + listViewerState: { + type: "object", + properties: { + muted: { + type: "boolean", + }, + blocked: { + type: "string", + format: "at-uri", + }, + }, + }, + notFoundActor: { + type: "object", + description: "indicates that a handle or DID could not be resolved", + required: ["actor", "notFound"], + properties: { + actor: { + type: "string", + format: "at-identifier", + }, + notFound: { + type: "boolean", + const: true, + }, + }, + }, + relationship: { + type: "object", + description: + "lists the bi-directional graph relationships between one actor (not indicated in the object), and the target actors (the DID included in the object)", + required: ["did"], + properties: { + did: { + type: "string", + format: "did", + }, + following: { + type: "string", + format: "at-uri", + description: + "if the actor follows this DID, this is the AT-URI of the follow record", + }, + followedBy: { + type: "string", + format: "at-uri", + description: + "if the actor is followed by this DID, contains the AT-URI of the follow record", + }, + }, + }, + }, + }, + SoSprkGraphFollow: { + lexicon: 1, + id: "so.sprk.graph.follow", + defs: { + main: { + type: "record", + description: + "Record declaring a social 'follow' relationship of another account. Duplicate follows will be ignored by the AppView.", + key: "tid", + record: { + type: "object", + required: ["subject", "createdAt"], + properties: { + subject: { + type: "string", + format: "did", + }, + createdAt: { + type: "string", + format: "datetime", + }, + }, + }, + }, + }, + }, + SoSprkGraphGetActorStarterPacks: { + lexicon: 1, + id: "so.sprk.graph.getActorStarterPacks", + defs: { + main: { + type: "query", + description: "Get a list of starter packs created by the actor.", + parameters: { + type: "params", + required: ["actor"], + properties: { + actor: { + type: "string", + format: "at-identifier", + }, + limit: { + type: "integer", + minimum: 1, + maximum: 100, + default: 50, + }, + cursor: { + type: "string", + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["starterPacks"], + properties: { + cursor: { + type: "string", + }, + starterPacks: { + type: "array", + items: { + type: "ref", + ref: "lex:so.sprk.graph.defs#starterPackViewBasic", + }, + }, + }, + }, + }, + }, + }, + }, + SoSprkGraphGetBlocks: { + lexicon: 1, + id: "so.sprk.graph.getBlocks", + defs: { + main: { + type: "query", + description: + "Enumerates which accounts the requesting account is currently blocking. Requires auth.", + parameters: { + type: "params", + properties: { + limit: { + type: "integer", + minimum: 1, + maximum: 100, + default: 50, + }, + cursor: { + type: "string", + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["blocks"], + properties: { + cursor: { + type: "string", + }, + blocks: { + type: "array", + items: { + type: "ref", + ref: "lex:so.sprk.actor.defs#profileView", + }, + }, + }, + }, + }, + }, + }, + }, + SoSprkGraphGetFollowers: { + lexicon: 1, + id: "so.sprk.graph.getFollowers", + defs: { + main: { + type: "query", + description: + "Enumerates accounts which follow a specified account (actor).", + parameters: { + type: "params", + required: ["actor"], + properties: { + actor: { + type: "string", + format: "at-identifier", + }, + limit: { + type: "integer", + minimum: 1, + maximum: 100, + default: 50, + }, + cursor: { + type: "string", + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["subject", "followers"], + properties: { + subject: { + type: "ref", + ref: "lex:so.sprk.actor.defs#profileView", + }, + cursor: { + type: "string", + }, + followers: { + type: "array", + items: { + type: "ref", + ref: "lex:so.sprk.actor.defs#profileView", + }, + }, + }, + }, + }, + }, + }, + }, + SoSprkGraphGetFollows: { + lexicon: 1, + id: "so.sprk.graph.getFollows", + defs: { + main: { + type: "query", + description: + "Enumerates accounts which a specified account (actor) follows.", + parameters: { + type: "params", + required: ["actor"], + properties: { + actor: { + type: "string", + format: "at-identifier", + }, + limit: { + type: "integer", + minimum: 1, + maximum: 100, + default: 50, + }, + cursor: { + type: "string", + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["subject", "follows"], + properties: { + subject: { + type: "ref", + ref: "lex:so.sprk.actor.defs#profileView", + }, + cursor: { + type: "string", + }, + follows: { + type: "array", + items: { + type: "ref", + ref: "lex:so.sprk.actor.defs#profileView", + }, + }, + }, + }, + }, + }, + }, + }, + SoSprkGraphGetKnownFollowers: { + lexicon: 1, + id: "so.sprk.graph.getKnownFollowers", + defs: { + main: { + type: "query", + description: + "Enumerates accounts which follow a specified account (actor) and are followed by the viewer.", + parameters: { + type: "params", + required: ["actor"], + properties: { + actor: { + type: "string", + format: "at-identifier", + }, + limit: { + type: "integer", + minimum: 1, + maximum: 100, + default: 50, + }, + cursor: { + type: "string", + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["subject", "followers"], + properties: { + subject: { + type: "ref", + ref: "lex:so.sprk.actor.defs#profileView", + }, + cursor: { + type: "string", + }, + followers: { + type: "array", + items: { + type: "ref", + ref: "lex:so.sprk.actor.defs#profileView", + }, + }, + }, + }, + }, + }, + }, + }, + SoSprkGraphGetListBlocks: { + lexicon: 1, + id: "so.sprk.graph.getListBlocks", + defs: { + main: { + type: "query", + description: + "Get mod lists that the requesting account (actor) is blocking. Requires auth.", + parameters: { + type: "params", + properties: { + limit: { + type: "integer", + minimum: 1, + maximum: 100, + default: 50, + }, + cursor: { + type: "string", + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["lists"], + properties: { + cursor: { + type: "string", + }, + lists: { + type: "array", + items: { + type: "ref", + ref: "lex:so.sprk.graph.defs#listView", + }, + }, + }, + }, + }, + }, + }, + }, + SoSprkGraphGetList: { + lexicon: 1, + id: "so.sprk.graph.getList", + defs: { + main: { + type: "query", + description: + "Gets a 'view' (with additional context) of a specified list.", + parameters: { + type: "params", + required: ["list"], + properties: { + list: { + type: "string", + format: "at-uri", + description: "Reference (AT-URI) of the list record to hydrate.", + }, + limit: { + type: "integer", + minimum: 1, + maximum: 100, + default: 50, + }, + cursor: { + type: "string", + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["list", "items"], + properties: { + cursor: { + type: "string", + }, + list: { + type: "ref", + ref: "lex:so.sprk.graph.defs#listView", + }, + items: { + type: "array", + items: { + type: "ref", + ref: "lex:so.sprk.graph.defs#listItemView", + }, + }, + }, + }, + }, + }, + }, + }, + SoSprkGraphGetListMutes: { + lexicon: 1, + id: "so.sprk.graph.getListMutes", + defs: { + main: { + type: "query", + description: + "Enumerates mod lists that the requesting account (actor) currently has muted. Requires auth.", + parameters: { + type: "params", + properties: { + limit: { + type: "integer", + minimum: 1, + maximum: 100, + default: 50, + }, + cursor: { + type: "string", + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["lists"], + properties: { + cursor: { + type: "string", + }, + lists: { + type: "array", + items: { + type: "ref", + ref: "lex:so.sprk.graph.defs#listView", + }, + }, + }, + }, + }, + }, + }, + }, + SoSprkGraphGetLists: { + lexicon: 1, + id: "so.sprk.graph.getLists", + defs: { + main: { + type: "query", + description: + "Enumerates the lists created by a specified account (actor).", + parameters: { + type: "params", + required: ["actor"], + properties: { + actor: { + type: "string", + format: "at-identifier", + description: "The account (actor) to enumerate lists from.", + }, + limit: { + type: "integer", + minimum: 1, + maximum: 100, + default: 50, + }, + cursor: { + type: "string", + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["lists"], + properties: { + cursor: { + type: "string", + }, + lists: { + type: "array", + items: { + type: "ref", + ref: "lex:so.sprk.graph.defs#listView", + }, + }, + }, + }, + }, + }, + }, + }, + SoSprkGraphGetMutes: { + lexicon: 1, + id: "so.sprk.graph.getMutes", + defs: { + main: { + type: "query", + description: + "Enumerates accounts that the requesting account (actor) currently has muted. Requires auth.", + parameters: { + type: "params", + properties: { + limit: { + type: "integer", + minimum: 1, + maximum: 100, + default: 50, + }, + cursor: { + type: "string", + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["mutes"], + properties: { + cursor: { + type: "string", + }, + mutes: { + type: "array", + items: { + type: "ref", + ref: "lex:so.sprk.actor.defs#profileView", + }, + }, + }, + }, + }, + }, + }, + }, + SoSprkGraphGetRelationships: { + lexicon: 1, + id: "so.sprk.graph.getRelationships", + defs: { + main: { + type: "query", + description: + "Enumerates public relationships between one account, and a list of other accounts. Does not require auth.", + parameters: { + type: "params", + required: ["actor"], + properties: { + actor: { + type: "string", + format: "at-identifier", + description: "Primary account requesting relationships for.", + }, + others: { + type: "array", + description: + "List of 'other' accounts to be related back to the primary.", + maxLength: 30, + items: { + type: "string", + format: "at-identifier", + }, + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["relationships"], + properties: { + actor: { + type: "string", + format: "did", + }, + relationships: { + type: "array", + items: { + type: "union", + refs: [ + "lex:so.sprk.graph.defs#relationship", + "lex:so.sprk.graph.defs#notFoundActor", + ], + }, + }, + }, + }, + }, + errors: [ + { + name: "ActorNotFound", + description: + "the primary actor at-identifier could not be resolved", + }, + ], + }, + }, + }, + SoSprkGraphGetStarterPack: { + lexicon: 1, + id: "so.sprk.graph.getStarterPack", + defs: { + main: { + type: "query", + description: "Gets a view of a starter pack.", + parameters: { + type: "params", + required: ["starterPack"], + properties: { + starterPack: { + type: "string", + format: "at-uri", + description: "Reference (AT-URI) of the starter pack record.", + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["starterPack"], + properties: { + starterPack: { + type: "ref", + ref: "lex:so.sprk.graph.defs#starterPackView", + }, + }, + }, + }, + }, + }, + }, + SoSprkGraphGetStarterPacks: { + lexicon: 1, + id: "so.sprk.graph.getStarterPacks", + defs: { + main: { + type: "query", + description: "Get views for a list of starter packs.", + parameters: { + type: "params", + required: ["uris"], + properties: { + uris: { + type: "array", + items: { + type: "string", + format: "at-uri", + }, + maxLength: 25, + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["starterPacks"], + properties: { + starterPacks: { + type: "array", + items: { + type: "ref", + ref: "lex:so.sprk.graph.defs#starterPackViewBasic", + }, + }, + }, + }, + }, + }, + }, + }, + SoSprkGraphGetSuggestedFollowsByActor: { + lexicon: 1, + id: "so.sprk.graph.getSuggestedFollowsByActor", + defs: { + main: { + type: "query", + description: + "Enumerates follows similar to a given account (actor). Expected use is to recommend additional accounts immediately after following one account.", + parameters: { + type: "params", + required: ["actor"], + properties: { + actor: { + type: "string", + format: "at-identifier", + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["suggestions"], + properties: { + suggestions: { + type: "array", + items: { + type: "ref", + ref: "lex:so.sprk.actor.defs#profileView", + }, + }, + isFallback: { + type: "boolean", + description: + "If true, response has fallen-back to generic results, and is not scoped using relativeToDid", + default: false, + }, + recId: { + type: "integer", + description: + "Snowflake for this recommendation, use when submitting recommendation events.", + }, + }, + }, + }, + }, + }, + }, + SoSprkGraphListblock: { + lexicon: 1, + id: "so.sprk.graph.listblock", + defs: { + main: { + type: "record", + description: + "Record representing a block relationship against an entire an entire list of accounts (actors).", + key: "tid", + record: { + type: "object", + required: ["subject", "createdAt"], + properties: { + subject: { + type: "string", + format: "at-uri", + description: "Reference (AT-URI) to the mod list record.", + }, + createdAt: { + type: "string", + format: "datetime", + }, + }, + }, + }, + }, + }, + SoSprkGraphListitem: { + lexicon: 1, + id: "so.sprk.graph.listitem", + defs: { + main: { + type: "record", + description: + "Record representing an account's inclusion on a specific list. The AppView will ignore duplicate listitem records.", + key: "tid", + record: { + type: "object", + required: ["subject", "list", "createdAt"], + properties: { + subject: { + type: "string", + format: "did", + description: "The account which is included on the list.", + }, + list: { + type: "string", + format: "at-uri", + description: + "Reference (AT-URI) to the list record (so.sprk.graph.list).", + }, + createdAt: { + type: "string", + format: "datetime", + }, + }, + }, + }, + }, + }, + SoSprkGraphList: { + lexicon: 1, + id: "so.sprk.graph.list", + defs: { + main: { + type: "record", + description: + "Record representing a list of accounts (actors). Scope includes both moderation-oriented lists and curration-oriented lists.", + key: "tid", + record: { + type: "object", + required: ["name", "purpose", "createdAt"], + properties: { + purpose: { + type: "ref", + description: + "Defines the purpose of the list (aka, moderation-oriented or curration-oriented)", + ref: "lex:so.sprk.graph.defs#listPurpose", + }, + name: { + type: "string", + maxLength: 64, + minLength: 1, + description: "Display name for list; can not be empty.", + }, + description: { + type: "string", + maxGraphemes: 300, + maxLength: 3000, + }, + descriptionFacets: { + type: "array", + items: { + type: "ref", + ref: "lex:so.sprk.richtext.facet", + }, + }, + avatar: { + type: "blob", + accept: ["image/png", "image/jpeg"], + maxSize: 1048576, + }, + labels: { + type: "union", + refs: ["lex:com.atproto.label.defs#selfLabels"], + }, + createdAt: { + type: "string", + format: "datetime", + }, + }, + }, + }, + }, + }, + SoSprkGraphMuteActor: { + lexicon: 1, + id: "so.sprk.graph.muteActor", + defs: { + main: { + type: "procedure", + description: + "Creates a mute relationship for the specified account. Mutes are private in Spark. Requires auth.", + input: { + encoding: "application/json", + schema: { + type: "object", + required: ["actor"], + properties: { + actor: { + type: "string", + format: "at-identifier", + }, + }, + }, + }, + }, + }, + }, + SoSprkGraphMuteActorList: { + lexicon: 1, + id: "so.sprk.graph.muteActorList", + defs: { + main: { + type: "procedure", + description: + "Creates a mute relationship for the specified list of accounts. Mutes are private in Spark. Requires auth.", + input: { + encoding: "application/json", + schema: { + type: "object", + required: ["list"], + properties: { + list: { + type: "string", + format: "at-uri", + }, + }, + }, + }, + }, + }, + }, + SoSprkGraphMuteThread: { + lexicon: 1, + id: "so.sprk.graph.muteThread", + defs: { + main: { + type: "procedure", + description: + "Mutes a thread preventing notifications from the thread and any of its children. Mutes are private in Spark. Requires auth.", + input: { + encoding: "application/json", + schema: { + type: "object", + required: ["root"], + properties: { + root: { + type: "string", + format: "at-uri", + }, + }, + }, + }, + }, + }, + }, + SoSprkGraphSearchStarterPacks: { + lexicon: 1, + id: "so.sprk.graph.searchStarterPacks", + defs: { + main: { + type: "query", + description: + "Find starter packs matching search criteria. Does not require auth.", + parameters: { + type: "params", + required: ["q"], + properties: { + q: { + type: "string", + description: + "Search query string. Syntax, phrase, boolean, and faceting is unspecified, but Lucene query syntax is recommended.", + }, + limit: { + type: "integer", + minimum: 1, + maximum: 100, + default: 25, + }, + cursor: { + type: "string", + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["starterPacks"], + properties: { + cursor: { + type: "string", + }, + starterPacks: { + type: "array", + items: { + type: "ref", + ref: "lex:so.sprk.graph.defs#starterPackViewBasic", + }, + }, + }, + }, + }, + }, + }, + }, + SoSprkGraphStarterpack: { + lexicon: 1, + id: "so.sprk.graph.starterpack", + defs: { + main: { + type: "record", + description: + "Record defining a starter pack of actors and feeds for new users.", + key: "tid", + record: { + type: "object", + required: ["name", "list", "createdAt"], + properties: { + name: { + type: "string", + maxGraphemes: 50, + maxLength: 500, + minLength: 1, + description: "Display name for starter pack; can not be empty.", + }, + description: { + type: "string", + maxGraphemes: 300, + maxLength: 3000, + }, + descriptionFacets: { + type: "array", + items: { + type: "ref", + ref: "lex:so.sprk.richtext.facet", + }, + }, + list: { + type: "string", + format: "at-uri", + description: "Reference (AT-URI) to the list record.", + }, + feeds: { + type: "array", + maxLength: 3, + items: { + type: "ref", + ref: "lex:so.sprk.graph.starterpack#feedItem", + }, + }, + createdAt: { + type: "string", + format: "datetime", + }, + }, + }, + }, + feedItem: { + type: "object", + required: ["uri"], + properties: { + uri: { + type: "string", + format: "at-uri", + }, + }, + }, + }, + }, + SoSprkGraphUnmuteActor: { + lexicon: 1, + id: "so.sprk.graph.unmuteActor", + defs: { + main: { + type: "procedure", + description: "Unmutes the specified account. Requires auth.", + input: { + encoding: "application/json", + schema: { + type: "object", + required: ["actor"], + properties: { + actor: { + type: "string", + format: "at-identifier", + }, + }, + }, + }, + }, + }, + }, + SoSprkGraphUnmuteActorList: { + lexicon: 1, + id: "so.sprk.graph.unmuteActorList", + defs: { + main: { + type: "procedure", + description: "Unmutes the specified list of accounts. Requires auth.", + input: { + encoding: "application/json", + schema: { + type: "object", + required: ["list"], + properties: { + list: { + type: "string", + format: "at-uri", + }, + }, + }, + }, + }, + }, + }, + SoSprkGraphUnmuteThread: { + lexicon: 1, + id: "so.sprk.graph.unmuteThread", + defs: { + main: { + type: "procedure", + description: "Unmutes the specified thread. Requires auth.", + input: { + encoding: "application/json", + schema: { + type: "object", + required: ["root"], + properties: { + root: { + type: "string", + format: "at-uri", + }, + }, + }, + }, + }, + }, + }, + SoSprkLabelerDefs: { + lexicon: 1, + id: "so.sprk.labeler.defs", + defs: { + labelerView: { + type: "object", + required: ["uri", "cid", "creator", "indexedAt"], + properties: { + uri: { + type: "string", + format: "at-uri", + }, + cid: { + type: "string", + format: "cid", + }, + creator: { + type: "ref", + ref: "lex:so.sprk.actor.defs#profileView", + }, + likeCount: { + type: "integer", + minimum: 0, + }, + lookCount: { + type: "integer", + minimum: 0, + }, + viewer: { + type: "ref", + ref: "lex:so.sprk.labeler.defs#labelerViewerState", + }, + indexedAt: { + type: "string", + format: "datetime", + }, + labels: { + type: "array", + items: { + type: "ref", + ref: "lex:com.atproto.label.defs#label", + }, + }, + }, + }, + labelerViewDetailed: { + type: "object", + required: ["uri", "cid", "creator", "policies", "indexedAt"], + properties: { + uri: { + type: "string", + format: "at-uri", + }, + cid: { + type: "string", + format: "cid", + }, + creator: { + type: "ref", + ref: "lex:so.sprk.actor.defs#profileView", + }, + policies: { + type: "ref", + ref: "lex:so.sprk.labeler.defs#labelerPolicies", + }, + likeCount: { + type: "integer", + minimum: 0, + }, + lookCount: { + type: "integer", + minimum: 0, + }, + viewer: { + type: "ref", + ref: "lex:so.sprk.labeler.defs#labelerViewerState", + }, + indexedAt: { + type: "string", + format: "datetime", + }, + labels: { + type: "array", + items: { + type: "ref", + ref: "lex:com.atproto.label.defs#label", + }, + }, + }, + }, + labelerViewerState: { + type: "object", + properties: { + like: { + type: "string", + format: "at-uri", + }, + look: { + type: "string", + format: "at-uri", + }, + }, + }, + labelerPolicies: { + type: "object", + required: ["labelValues"], + properties: { + labelValues: { + type: "array", + description: + "The label values which this labeler publishes. May include global or custom labels.", + items: { + type: "ref", + ref: "lex:com.atproto.label.defs#labelValue", + }, + }, + labelValueDefinitions: { + type: "array", + description: + "Label values created by this labeler and scoped exclusively to it. Labels defined here will override global label definitions for this labeler.", + items: { + type: "ref", + ref: "lex:com.atproto.label.defs#labelValueDefinition", + }, + }, + }, + }, + }, + }, + SoSprkLabelerGetServices: { + lexicon: 1, + id: "so.sprk.labeler.getServices", + defs: { + main: { + type: "query", + description: "Get information about a list of labeler services.", + parameters: { + type: "params", + required: ["dids"], + properties: { + dids: { + type: "array", + items: { + type: "string", + format: "did", + }, + }, + detailed: { + type: "boolean", + default: false, + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["views"], + properties: { + views: { + type: "array", + items: { + type: "union", + refs: [ + "lex:so.sprk.labeler.defs#labelerView", + "lex:so.sprk.labeler.defs#labelerViewDetailed", + ], + }, + }, + }, + }, + }, + }, + }, + }, + SoSprkLabelerService: { + lexicon: 1, + id: "so.sprk.labeler.service", + defs: { + main: { + type: "record", + description: "A declaration of the existence of labeler service.", + key: "literal:self", + record: { + type: "object", + required: ["policies", "createdAt"], + properties: { + policies: { + type: "ref", + ref: "lex:so.sprk.labeler.defs#labelerPolicies", + }, + labels: { + type: "union", + refs: ["lex:com.atproto.label.defs#selfLabels"], + }, + createdAt: { + type: "string", + format: "datetime", + }, + }, + }, + }, + }, + }, + SoSprkNotificationGetUnreadCount: { + lexicon: 1, + id: "so.sprk.notification.getUnreadCount", + defs: { + main: { + type: "query", + description: + "Count the number of unread notifications for the requesting account. Requires auth.", + parameters: { + type: "params", + properties: { + priority: { + type: "boolean", + }, + seenAt: { + type: "string", + format: "datetime", + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["count"], + properties: { + count: { + type: "integer", + }, + }, + }, + }, + }, + }, + }, + SoSprkNotificationListNotifications: { + lexicon: 1, + id: "so.sprk.notification.listNotifications", + defs: { + main: { + type: "query", + description: + "Enumerate notifications for the requesting account. Requires auth.", + parameters: { + type: "params", + properties: { + reasons: { + description: "Notification reasons to include in response.", + type: "array", + items: { + type: "string", + description: + "A reason that matches the reason property of #notification.", + }, + }, + limit: { + type: "integer", + minimum: 1, + maximum: 100, + default: 50, + }, + priority: { + type: "boolean", + }, + cursor: { + type: "string", + }, + seenAt: { + type: "string", + format: "datetime", + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["notifications"], + properties: { + cursor: { + type: "string", + }, + notifications: { + type: "array", + items: { + type: "ref", + ref: + "lex:so.sprk.notification.listNotifications#notification", + }, + }, + priority: { + type: "boolean", + }, + seenAt: { + type: "string", + format: "datetime", + }, + }, + }, + }, + }, + notification: { + type: "object", + required: [ + "uri", + "cid", + "author", + "reason", + "record", + "isRead", + "indexedAt", + ], + properties: { + uri: { + type: "string", + format: "at-uri", + }, + cid: { + type: "string", + format: "cid", + }, + author: { + type: "ref", + ref: "lex:so.sprk.actor.defs#profileView", + }, + reason: { + type: "string", + description: + "Expected values are 'like', 'repost', 'follow', 'mention', 'reply', 'quote', and 'starterpack-joined'.", + knownValues: [ + "like", + "repost", + "follow", + "mention", + "reply", + "quote", + "starterpack-joined", + ], + }, + reasonSubject: { + type: "string", + format: "at-uri", + }, + record: { + type: "unknown", + }, + isRead: { + type: "boolean", + }, + indexedAt: { + type: "string", + format: "datetime", + }, + labels: { + type: "array", + items: { + type: "ref", + ref: "lex:com.atproto.label.defs#label", + }, + }, + }, + }, + }, + }, + SoSprkNotificationPutPreferences: { + lexicon: 1, + id: "so.sprk.notification.putPreferences", + defs: { + main: { + type: "procedure", + description: + "Set notification-related preferences for an account. Requires auth.", + input: { + encoding: "application/json", + schema: { + type: "object", + required: ["priority"], + properties: { + priority: { + type: "boolean", + }, + }, + }, + }, + }, + }, + }, + SoSprkNotificationRegisterPush: { + lexicon: 1, + id: "so.sprk.notification.registerPush", + defs: { + main: { + type: "procedure", + description: + "Register to receive push notifications, via a specified service, for the requesting account. Requires auth.", + input: { + encoding: "application/json", + schema: { + type: "object", + required: ["serviceDid", "token", "platform", "appId"], + properties: { + serviceDid: { + type: "string", + format: "did", + }, + token: { + type: "string", + }, + platform: { + type: "string", + knownValues: ["ios", "android", "web"], + }, + appId: { + type: "string", + }, + }, + }, + }, + }, + }, + }, + SoSprkNotificationUpdateSeen: { + lexicon: 1, + id: "so.sprk.notification.updateSeen", + defs: { + main: { + type: "procedure", + description: + "Notify server that the requesting account has seen notifications. Requires auth.", + input: { + encoding: "application/json", + schema: { + type: "object", + required: ["seenAt"], + properties: { + seenAt: { + type: "string", + format: "datetime", + }, + }, + }, + }, + }, + }, + }, + SoSprkRichtextFacet: { + lexicon: 1, + id: "so.sprk.richtext.facet", + defs: { + main: { + type: "object", + description: "Annotation of a sub-string within rich text.", + required: ["index", "features"], + properties: { + index: { + type: "ref", + ref: "lex:so.sprk.richtext.facet#byteSlice", + }, + features: { + type: "array", + items: { + type: "union", + refs: [ + "lex:so.sprk.richtext.facet#mention", + "lex:so.sprk.richtext.facet#link", + "lex:so.sprk.richtext.facet#tag", + ], + }, + }, + }, + }, + mention: { + type: "object", + description: + "Facet feature for mention of another account. The text is usually a handle, including a '@' prefix, but the facet reference is a DID.", + required: ["did"], + properties: { + did: { + type: "string", + format: "did", + }, + }, + }, + link: { + type: "object", + description: + "Facet feature for a URL. The text URL may have been simplified or truncated, but the facet reference should be a complete URL.", + required: ["uri"], + properties: { + uri: { + type: "string", + format: "uri", + }, + }, + }, + tag: { + type: "object", + description: + "Facet feature for a hashtag. The text usually includes a '#' prefix, but the facet reference should not (except in the case of 'double hash tags').", + required: ["tag"], + properties: { + tag: { + type: "string", + maxLength: 640, + maxGraphemes: 64, + }, + }, + }, + byteSlice: { + type: "object", + description: + "Specifies the sub-string range a facet feature applies to. Start index is inclusive, end index is exclusive. Indices are zero-indexed, counting bytes of the UTF-8 encoded text. NOTE: some languages, like Javascript, use UTF-16 or Unicode codepoints for string slice indexing; in these languages, convert to byte arrays before working with facets.", + required: ["byteStart", "byteEnd"], + properties: { + byteStart: { + type: "integer", + minimum: 0, + }, + byteEnd: { + type: "integer", + minimum: 0, + }, + }, + }, + }, + }, + SoSprkUnspeccedDefs: { + lexicon: 1, + id: "so.sprk.unspecced.defs", + defs: { + skeletonSearchPost: { + type: "object", + required: ["uri"], + properties: { + uri: { + type: "string", + format: "at-uri", + }, + }, + }, + skeletonSearchActor: { + type: "object", + required: ["did"], + properties: { + did: { + type: "string", + format: "did", + }, + }, + }, + skeletonSearchStarterPack: { + type: "object", + required: ["uri"], + properties: { + uri: { + type: "string", + format: "at-uri", + }, + }, + }, + trendingTopic: { + type: "object", + required: ["topic", "link"], + properties: { + topic: { + type: "string", + }, + displayName: { + type: "string", + }, + description: { + type: "string", + }, + link: { + type: "string", + }, + }, + }, + }, + }, + SoSprkUnspeccedGetConfig: { + lexicon: 1, + id: "so.sprk.unspecced.getConfig", + defs: { + main: { + type: "query", + description: "Get miscellaneous runtime configuration.", + output: { + encoding: "application/json", + schema: { + type: "object", + required: [], + properties: { + checkEmailConfirmed: { + type: "boolean", + }, + }, + }, + }, + }, + }, + }, + SoSprkUnspeccedGetPopularFeedGenerators: { + lexicon: 1, + id: "so.sprk.unspecced.getPopularFeedGenerators", + defs: { + main: { + type: "query", + description: "An unspecced view of globally popular feed generators.", + parameters: { + type: "params", + properties: { + limit: { + type: "integer", + minimum: 1, + maximum: 100, + default: 50, + }, + cursor: { + type: "string", + }, + query: { + type: "string", + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["feeds"], + properties: { + cursor: { + type: "string", + }, + feeds: { + type: "array", + items: { + type: "ref", + ref: "lex:so.sprk.feed.defs#generatorView", + }, + }, + }, + }, + }, + }, + }, + }, + SoSprkUnspeccedGetSuggestionsSkeleton: { + lexicon: 1, + id: "so.sprk.unspecced.getSuggestionsSkeleton", + defs: { + main: { + type: "query", + description: + "Get a skeleton of suggested actors. Intended to be called and then hydrated through so.sprk.actor.getSuggestions", + parameters: { + type: "params", + properties: { + viewer: { + type: "string", + format: "did", + description: + "DID of the account making the request (not included for public/unauthenticated queries). Used to boost followed accounts in ranking.", + }, + limit: { + type: "integer", + minimum: 1, + maximum: 100, + default: 50, + }, + cursor: { + type: "string", + }, + relativeToDid: { + type: "string", + format: "did", + description: + "DID of the account to get suggestions relative to. If not provided, suggestions will be based on the viewer.", + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["actors"], + properties: { + cursor: { + type: "string", + }, + actors: { + type: "array", + items: { + type: "ref", + ref: "lex:so.sprk.unspecced.defs#skeletonSearchActor", + }, + }, + relativeToDid: { + type: "string", + format: "did", + description: + "DID of the account these suggestions are relative to. If this is returned undefined, suggestions are based on the viewer.", + }, + recId: { + type: "integer", + description: + "Snowflake for this recommendation, use when submitting recommendation events.", + }, + }, + }, + }, + }, + }, + }, + SoSprkUnspeccedGetTaggedSuggestions: { + lexicon: 1, + id: "so.sprk.unspecced.getTaggedSuggestions", + defs: { + main: { + type: "query", + description: + "Get a list of suggestions (feeds and users) tagged with categories", + parameters: { + type: "params", + properties: {}, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["suggestions"], + properties: { + suggestions: { + type: "array", + items: { + type: "ref", + ref: "lex:so.sprk.unspecced.getTaggedSuggestions#suggestion", + }, + }, + }, + }, + }, + }, + suggestion: { + type: "object", + required: ["tag", "subjectType", "subject"], + properties: { + tag: { + type: "string", + }, + subjectType: { + type: "string", + knownValues: ["actor", "feed"], + }, + subject: { + type: "string", + format: "uri", + }, + }, + }, + }, + }, + SoSprkUnspeccedGetTrendingTopics: { + lexicon: 1, + id: "so.sprk.unspecced.getTrendingTopics", + defs: { + main: { + type: "query", + description: "Get a list of trending topics", + parameters: { + type: "params", + properties: { + viewer: { + type: "string", + format: "did", + description: + "DID of the account making the request (not included for public/unauthenticated queries). Used to boost followed accounts in ranking.", + }, + limit: { + type: "integer", + minimum: 1, + maximum: 25, + default: 10, + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["topics", "suggested"], + properties: { + topics: { + type: "array", + items: { + type: "ref", + ref: "lex:so.sprk.unspecced.defs#trendingTopic", + }, + }, + suggested: { + type: "array", + items: { + type: "ref", + ref: "lex:so.sprk.unspecced.defs#trendingTopic", + }, + }, + }, + }, + }, + }, + }, + }, + SoSprkUnspeccedSearchActorsSkeleton: { + lexicon: 1, + id: "so.sprk.unspecced.searchActorsSkeleton", + defs: { + main: { + type: "query", + description: "Backend Actors (profile) search, returns only skeleton.", + parameters: { + type: "params", + required: ["q"], + properties: { + q: { + type: "string", + description: + "Search query string; syntax, phrase, boolean, and faceting is unspecified, but Lucene query syntax is recommended. For typeahead search, only simple term match is supported, not full syntax.", + }, + viewer: { + type: "string", + format: "did", + description: + "DID of the account making the request (not included for public/unauthenticated queries). Used to boost followed accounts in ranking.", + }, + typeahead: { + type: "boolean", + description: "If true, acts as fast/simple 'typeahead' query.", + }, + limit: { + type: "integer", + minimum: 1, + maximum: 100, + default: 25, + }, + cursor: { + type: "string", + description: + "Optional pagination mechanism; may not necessarily allow scrolling through entire result set.", + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["actors"], + properties: { + cursor: { + type: "string", + }, + hitsTotal: { + type: "integer", + description: + "Count of search hits. Optional, may be rounded/truncated, and may not be possible to paginate through all hits.", + }, + actors: { + type: "array", + items: { + type: "ref", + ref: "lex:so.sprk.unspecced.defs#skeletonSearchActor", + }, + }, + }, + }, + }, + errors: [ + { + name: "BadQueryString", + }, + ], + }, + }, + }, + SoSprkUnspeccedSearchPostsSkeleton: { + lexicon: 1, + id: "so.sprk.unspecced.searchPostsSkeleton", + defs: { + main: { + type: "query", + description: "Backend Posts search, returns only skeleton", + parameters: { + type: "params", + required: ["q"], + properties: { + q: { + type: "string", + description: + "Search query string; syntax, phrase, boolean, and faceting is unspecified, but Lucene query syntax is recommended.", + }, + sort: { + type: "string", + knownValues: ["top", "latest"], + default: "latest", + description: "Specifies the ranking order of results.", + }, + since: { + type: "string", + description: + "Filter results for posts after the indicated datetime (inclusive). Expected to use 'sortAt' timestamp, which may not match 'createdAt'. Can be a datetime, or just an ISO date (YYYY-MM-DD).", + }, + until: { + type: "string", + description: + "Filter results for posts before the indicated datetime (not inclusive). Expected to use 'sortAt' timestamp, which may not match 'createdAt'. Can be a datetime, or just an ISO date (YYY-MM-DD).", + }, + mentions: { + type: "string", + format: "at-identifier", + description: + "Filter to posts which mention the given account. Handles are resolved to DID before query-time. Only matches rich-text facet mentions.", + }, + author: { + type: "string", + format: "at-identifier", + description: + "Filter to posts by the given account. Handles are resolved to DID before query-time.", + }, + lang: { + type: "string", + format: "language", + description: + "Filter to posts in the given language. Expected to be based on post language field, though server may override language detection.", + }, + domain: { + type: "string", + description: + "Filter to posts with URLs (facet links or embeds) linking to the given domain (hostname). Server may apply hostname normalization.", + }, + url: { + type: "string", + format: "uri", + description: + "Filter to posts with links (facet links or embeds) pointing to this URL. Server may apply URL normalization or fuzzy matching.", + }, + tag: { + type: "array", + items: { + type: "string", + maxLength: 640, + maxGraphemes: 64, + }, + description: + "Filter to posts with the given tag (hashtag), based on rich-text facet or tag field. Do not include the hash (#) prefix. Multiple tags can be specified, with 'AND' matching.", + }, + viewer: { + type: "string", + format: "did", + description: + "DID of the account making the request (not included for public/unauthenticated queries). Used for 'from:me' queries.", + }, + limit: { + type: "integer", + minimum: 1, + maximum: 100, + default: 25, + }, + cursor: { + type: "string", + description: + "Optional pagination mechanism; may not necessarily allow scrolling through entire result set.", + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["posts"], + properties: { + cursor: { + type: "string", + }, + hitsTotal: { + type: "integer", + description: + "Count of search hits. Optional, may be rounded/truncated, and may not be possible to paginate through all hits.", + }, + posts: { + type: "array", + items: { + type: "ref", + ref: "lex:so.sprk.unspecced.defs#skeletonSearchPost", + }, + }, + }, + }, + }, + errors: [ + { + name: "BadQueryString", + }, + ], + }, + }, + }, + SoSprkUnspeccedSearchStarterPacksSkeleton: { + lexicon: 1, + id: "so.sprk.unspecced.searchStarterPacksSkeleton", + defs: { + main: { + type: "query", + description: "Backend Starter Pack search, returns only skeleton.", + parameters: { + type: "params", + required: ["q"], + properties: { + q: { + type: "string", + description: + "Search query string; syntax, phrase, boolean, and faceting is unspecified, but Lucene query syntax is recommended.", + }, + viewer: { + type: "string", + format: "did", + description: + "DID of the account making the request (not included for public/unauthenticated queries).", + }, + limit: { + type: "integer", + minimum: 1, + maximum: 100, + default: 25, + }, + cursor: { + type: "string", + description: + "Optional pagination mechanism; may not necessarily allow scrolling through entire result set.", + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["starterPacks"], + properties: { + cursor: { + type: "string", + }, + hitsTotal: { + type: "integer", + description: + "Count of search hits. Optional, may be rounded/truncated, and may not be possible to paginate through all hits.", + }, + starterPacks: { + type: "array", + items: { + type: "ref", + ref: "lex:so.sprk.unspecced.defs#skeletonSearchStarterPack", + }, + }, + }, + }, + }, + errors: [ + { + name: "BadQueryString", + }, + ], + }, + }, + }, + SoSprkVideoDefs: { + lexicon: 1, + id: "so.sprk.video.defs", + defs: { + jobStatus: { + type: "object", + required: ["jobId", "did", "state"], + properties: { + jobId: { + type: "string", + }, + did: { + type: "string", + format: "did", + }, + state: { + type: "string", + description: + "The state of the video processing job. All values not listed as a known value indicate that the job is in process.", + knownValues: ["JOB_STATE_COMPLETED", "JOB_STATE_FAILED"], + }, + progress: { + type: "integer", + minimum: 0, + maximum: 100, + description: "Progress within the current processing state.", + }, + blob: { + type: "blob", + }, + error: { + type: "string", + }, + message: { + type: "string", + }, + }, + }, + }, + }, + SoSprkVideoGetJobStatus: { + lexicon: 1, + id: "so.sprk.video.getJobStatus", + defs: { + main: { + type: "query", + description: "Get status details for a video processing job.", + parameters: { + type: "params", + required: ["jobId"], + properties: { + jobId: { + type: "string", + }, + }, + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["jobStatus"], + properties: { + jobStatus: { + type: "ref", + ref: "lex:so.sprk.video.defs#jobStatus", + }, + }, + }, + }, + }, + }, + }, + SoSprkVideoGetUploadLimits: { + lexicon: 1, + id: "so.sprk.video.getUploadLimits", + defs: { + main: { + type: "query", + description: "Get video upload limits for the authenticated user.", + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["canUpload"], + properties: { + canUpload: { + type: "boolean", + }, + remainingDailyVideos: { + type: "integer", + }, + remainingDailyBytes: { + type: "integer", + }, + message: { + type: "string", + }, + error: { + type: "string", + }, + }, + }, + }, + }, + }, + }, + SoSprkVideoUploadVideo: { + lexicon: 1, + id: "so.sprk.video.uploadVideo", + defs: { + main: { + type: "procedure", + description: "Upload a video to be processed then stored on the PDS.", + input: { + encoding: "video/mp4", + }, + output: { + encoding: "application/json", + schema: { + type: "object", + required: ["jobStatus"], + properties: { + jobStatus: { + type: "ref", + ref: "lex:so.sprk.video.defs#jobStatus", + }, + }, + }, + }, + }, + }, + }, +} as const satisfies Record; + +export const schemas = Object.values(schemaDict) satisfies LexiconDoc[]; +export const lexicons: Lexicons = new Lexicons(schemas); + +export function validate( + v: unknown, + id: string, + hash: string, + requiredType: true, +): ValidationResult; +export function validate( + v: unknown, + id: string, + hash: string, + requiredType?: false, +): ValidationResult; +export function validate( + v: unknown, + id: string, + hash: string, + requiredType?: boolean, +): ValidationResult { + return (requiredType ? is$typed : maybe$typed)(v, id, hash) + ? lexicons.validate(`${id}#${hash}`, v) + : { + success: false, + error: new ValidationError( + `Must be an object with "${ + hash === "main" ? id : `${id}#${hash}` + }" $type property`, + ), + }; +} + +export const ids = { + ComAtprotoAdminDefs: "com.atproto.admin.defs", + ComAtprotoAdminDeleteAccount: "com.atproto.admin.deleteAccount", + ComAtprotoAdminDisableAccountInvites: + "com.atproto.admin.disableAccountInvites", + ComAtprotoAdminDisableInviteCodes: "com.atproto.admin.disableInviteCodes", + ComAtprotoAdminEnableAccountInvites: "com.atproto.admin.enableAccountInvites", + ComAtprotoAdminGetAccountInfo: "com.atproto.admin.getAccountInfo", + ComAtprotoAdminGetAccountInfos: "com.atproto.admin.getAccountInfos", + ComAtprotoAdminGetInviteCodes: "com.atproto.admin.getInviteCodes", + ComAtprotoAdminGetSubjectStatus: "com.atproto.admin.getSubjectStatus", + ComAtprotoAdminSearchAccounts: "com.atproto.admin.searchAccounts", + ComAtprotoAdminSendEmail: "com.atproto.admin.sendEmail", + ComAtprotoAdminUpdateAccountEmail: "com.atproto.admin.updateAccountEmail", + ComAtprotoAdminUpdateAccountHandle: "com.atproto.admin.updateAccountHandle", + ComAtprotoAdminUpdateAccountPassword: + "com.atproto.admin.updateAccountPassword", + ComAtprotoAdminUpdateSubjectStatus: "com.atproto.admin.updateSubjectStatus", + ComAtprotoIdentityGetRecommendedDidCredentials: + "com.atproto.identity.getRecommendedDidCredentials", + ComAtprotoIdentityRequestPlcOperationSignature: + "com.atproto.identity.requestPlcOperationSignature", + ComAtprotoIdentityResolveHandle: "com.atproto.identity.resolveHandle", + ComAtprotoIdentitySignPlcOperation: "com.atproto.identity.signPlcOperation", + ComAtprotoIdentitySubmitPlcOperation: + "com.atproto.identity.submitPlcOperation", + ComAtprotoIdentityUpdateHandle: "com.atproto.identity.updateHandle", + ComAtprotoLabelDefs: "com.atproto.label.defs", + ComAtprotoLabelQueryLabels: "com.atproto.label.queryLabels", + ComAtprotoLabelSubscribeLabels: "com.atproto.label.subscribeLabels", + ComAtprotoLexiconSchema: "com.atproto.lexicon.schema", + ComAtprotoModerationCreateReport: "com.atproto.moderation.createReport", + ComAtprotoModerationDefs: "com.atproto.moderation.defs", + ComAtprotoRepoApplyWrites: "com.atproto.repo.applyWrites", + ComAtprotoRepoCreateRecord: "com.atproto.repo.createRecord", + ComAtprotoRepoDefs: "com.atproto.repo.defs", + ComAtprotoRepoDeleteRecord: "com.atproto.repo.deleteRecord", + ComAtprotoRepoDescribeRepo: "com.atproto.repo.describeRepo", + ComAtprotoRepoGetRecord: "com.atproto.repo.getRecord", + ComAtprotoRepoImportRepo: "com.atproto.repo.importRepo", + ComAtprotoRepoListMissingBlobs: "com.atproto.repo.listMissingBlobs", + ComAtprotoRepoListRecords: "com.atproto.repo.listRecords", + ComAtprotoRepoPutRecord: "com.atproto.repo.putRecord", + ComAtprotoRepoStrongRef: "com.atproto.repo.strongRef", + ComAtprotoRepoUploadBlob: "com.atproto.repo.uploadBlob", + ComAtprotoServerActivateAccount: "com.atproto.server.activateAccount", + ComAtprotoServerCheckAccountStatus: "com.atproto.server.checkAccountStatus", + ComAtprotoServerConfirmEmail: "com.atproto.server.confirmEmail", + ComAtprotoServerCreateAccount: "com.atproto.server.createAccount", + ComAtprotoServerCreateAppPassword: "com.atproto.server.createAppPassword", + ComAtprotoServerCreateInviteCode: "com.atproto.server.createInviteCode", + ComAtprotoServerCreateInviteCodes: "com.atproto.server.createInviteCodes", + ComAtprotoServerCreateSession: "com.atproto.server.createSession", + ComAtprotoServerDeactivateAccount: "com.atproto.server.deactivateAccount", + ComAtprotoServerDefs: "com.atproto.server.defs", + ComAtprotoServerDeleteAccount: "com.atproto.server.deleteAccount", + ComAtprotoServerDeleteSession: "com.atproto.server.deleteSession", + ComAtprotoServerDescribeServer: "com.atproto.server.describeServer", + ComAtprotoServerGetAccountInviteCodes: + "com.atproto.server.getAccountInviteCodes", + ComAtprotoServerGetServiceAuth: "com.atproto.server.getServiceAuth", + ComAtprotoServerGetSession: "com.atproto.server.getSession", + ComAtprotoServerListAppPasswords: "com.atproto.server.listAppPasswords", + ComAtprotoServerRefreshSession: "com.atproto.server.refreshSession", + ComAtprotoServerRequestAccountDelete: + "com.atproto.server.requestAccountDelete", + ComAtprotoServerRequestEmailConfirmation: + "com.atproto.server.requestEmailConfirmation", + ComAtprotoServerRequestEmailUpdate: "com.atproto.server.requestEmailUpdate", + ComAtprotoServerRequestPasswordReset: + "com.atproto.server.requestPasswordReset", + ComAtprotoServerReserveSigningKey: "com.atproto.server.reserveSigningKey", + ComAtprotoServerResetPassword: "com.atproto.server.resetPassword", + ComAtprotoServerRevokeAppPassword: "com.atproto.server.revokeAppPassword", + ComAtprotoServerUpdateEmail: "com.atproto.server.updateEmail", + ComAtprotoSyncGetBlob: "com.atproto.sync.getBlob", + ComAtprotoSyncGetBlocks: "com.atproto.sync.getBlocks", + ComAtprotoSyncGetCheckout: "com.atproto.sync.getCheckout", + ComAtprotoSyncGetHead: "com.atproto.sync.getHead", + ComAtprotoSyncGetLatestCommit: "com.atproto.sync.getLatestCommit", + ComAtprotoSyncGetRecord: "com.atproto.sync.getRecord", + ComAtprotoSyncGetRepo: "com.atproto.sync.getRepo", + ComAtprotoSyncGetRepoStatus: "com.atproto.sync.getRepoStatus", + ComAtprotoSyncListBlobs: "com.atproto.sync.listBlobs", + ComAtprotoSyncListReposByCollection: "com.atproto.sync.listReposByCollection", + ComAtprotoSyncListRepos: "com.atproto.sync.listRepos", + ComAtprotoSyncNotifyOfUpdate: "com.atproto.sync.notifyOfUpdate", + ComAtprotoSyncRequestCrawl: "com.atproto.sync.requestCrawl", + ComAtprotoSyncSubscribeRepos: "com.atproto.sync.subscribeRepos", + ComAtprotoTempAddReservedHandle: "com.atproto.temp.addReservedHandle", + ComAtprotoTempCheckSignupQueue: "com.atproto.temp.checkSignupQueue", + ComAtprotoTempFetchLabels: "com.atproto.temp.fetchLabels", + ComAtprotoTempRequestPhoneVerification: + "com.atproto.temp.requestPhoneVerification", + SoSprkActorDefs: "so.sprk.actor.defs", + SoSprkActorGetPreferences: "so.sprk.actor.getPreferences", + SoSprkActorGetProfile: "so.sprk.actor.getProfile", + SoSprkActorGetProfiles: "so.sprk.actor.getProfiles", + SoSprkActorGetSuggestions: "so.sprk.actor.getSuggestions", + SoSprkActorProfile: "so.sprk.actor.profile", + SoSprkActorPutPreferences: "so.sprk.actor.putPreferences", + SoSprkActorSearchActors: "so.sprk.actor.searchActors", + SoSprkActorSearchActorsTypeahead: "so.sprk.actor.searchActorsTypeahead", + SoSprkEmbedDefs: "so.sprk.embed.defs", + SoSprkEmbedImages: "so.sprk.embed.images", + SoSprkEmbedVideo: "so.sprk.embed.video", + SoSprkFeedDefs: "so.sprk.feed.defs", + SoSprkFeedDescribeFeedGenerator: "so.sprk.feed.describeFeedGenerator", + SoSprkFeedGenerator: "so.sprk.feed.generator", + SoSprkFeedGetActorFeeds: "so.sprk.feed.getActorFeeds", + SoSprkFeedGetActorLikes: "so.sprk.feed.getActorLikes", + SoSprkFeedGetActorLooks: "so.sprk.feed.getActorLooks", + SoSprkFeedGetAuthorFeed: "so.sprk.feed.getAuthorFeed", + SoSprkFeedGetFeedGenerator: "so.sprk.feed.getFeedGenerator", + SoSprkFeedGetFeedGenerators: "so.sprk.feed.getFeedGenerators", + SoSprkFeedGetFeed: "so.sprk.feed.getFeed", + SoSprkFeedGetFeedSkeleton: "so.sprk.feed.getFeedSkeleton", + SoSprkFeedGetLikes: "so.sprk.feed.getLikes", + SoSprkFeedGetListFeed: "so.sprk.feed.getListFeed", + SoSprkFeedGetLooks: "so.sprk.feed.getLooks", + SoSprkFeedGetPosts: "so.sprk.feed.getPosts", + SoSprkFeedGetPostThread: "so.sprk.feed.getPostThread", + SoSprkFeedGetQuotes: "so.sprk.feed.getQuotes", + SoSprkFeedGetRepostedBy: "so.sprk.feed.getRepostedBy", + SoSprkFeedGetSuggestedFeeds: "so.sprk.feed.getSuggestedFeeds", + SoSprkFeedGetTimeline: "so.sprk.feed.getTimeline", + SoSprkFeedLike: "so.sprk.feed.like", + SoSprkFeedLook: "so.sprk.feed.look", + SoSprkFeedPostgate: "so.sprk.feed.postgate", + SoSprkFeedPost: "so.sprk.feed.post", + SoSprkFeedRepost: "so.sprk.feed.repost", + SoSprkFeedSearchPosts: "so.sprk.feed.searchPosts", + SoSprkFeedSendInteractions: "so.sprk.feed.sendInteractions", + SoSprkFeedThreadgate: "so.sprk.feed.threadgate", + SoSprkGraphBlock: "so.sprk.graph.block", + SoSprkGraphDefs: "so.sprk.graph.defs", + SoSprkGraphFollow: "so.sprk.graph.follow", + SoSprkGraphGetActorStarterPacks: "so.sprk.graph.getActorStarterPacks", + SoSprkGraphGetBlocks: "so.sprk.graph.getBlocks", + SoSprkGraphGetFollowers: "so.sprk.graph.getFollowers", + SoSprkGraphGetFollows: "so.sprk.graph.getFollows", + SoSprkGraphGetKnownFollowers: "so.sprk.graph.getKnownFollowers", + SoSprkGraphGetListBlocks: "so.sprk.graph.getListBlocks", + SoSprkGraphGetList: "so.sprk.graph.getList", + SoSprkGraphGetListMutes: "so.sprk.graph.getListMutes", + SoSprkGraphGetLists: "so.sprk.graph.getLists", + SoSprkGraphGetMutes: "so.sprk.graph.getMutes", + SoSprkGraphGetRelationships: "so.sprk.graph.getRelationships", + SoSprkGraphGetStarterPack: "so.sprk.graph.getStarterPack", + SoSprkGraphGetStarterPacks: "so.sprk.graph.getStarterPacks", + SoSprkGraphGetSuggestedFollowsByActor: + "so.sprk.graph.getSuggestedFollowsByActor", + SoSprkGraphListblock: "so.sprk.graph.listblock", + SoSprkGraphListitem: "so.sprk.graph.listitem", + SoSprkGraphList: "so.sprk.graph.list", + SoSprkGraphMuteActor: "so.sprk.graph.muteActor", + SoSprkGraphMuteActorList: "so.sprk.graph.muteActorList", + SoSprkGraphMuteThread: "so.sprk.graph.muteThread", + SoSprkGraphSearchStarterPacks: "so.sprk.graph.searchStarterPacks", + SoSprkGraphStarterpack: "so.sprk.graph.starterpack", + SoSprkGraphUnmuteActor: "so.sprk.graph.unmuteActor", + SoSprkGraphUnmuteActorList: "so.sprk.graph.unmuteActorList", + SoSprkGraphUnmuteThread: "so.sprk.graph.unmuteThread", + SoSprkLabelerDefs: "so.sprk.labeler.defs", + SoSprkLabelerGetServices: "so.sprk.labeler.getServices", + SoSprkLabelerService: "so.sprk.labeler.service", + SoSprkNotificationGetUnreadCount: "so.sprk.notification.getUnreadCount", + SoSprkNotificationListNotifications: "so.sprk.notification.listNotifications", + SoSprkNotificationPutPreferences: "so.sprk.notification.putPreferences", + SoSprkNotificationRegisterPush: "so.sprk.notification.registerPush", + SoSprkNotificationUpdateSeen: "so.sprk.notification.updateSeen", + SoSprkRichtextFacet: "so.sprk.richtext.facet", + SoSprkUnspeccedDefs: "so.sprk.unspecced.defs", + SoSprkUnspeccedGetConfig: "so.sprk.unspecced.getConfig", + SoSprkUnspeccedGetPopularFeedGenerators: + "so.sprk.unspecced.getPopularFeedGenerators", + SoSprkUnspeccedGetSuggestionsSkeleton: + "so.sprk.unspecced.getSuggestionsSkeleton", + SoSprkUnspeccedGetTaggedSuggestions: "so.sprk.unspecced.getTaggedSuggestions", + SoSprkUnspeccedGetTrendingTopics: "so.sprk.unspecced.getTrendingTopics", + SoSprkUnspeccedSearchActorsSkeleton: "so.sprk.unspecced.searchActorsSkeleton", + SoSprkUnspeccedSearchPostsSkeleton: "so.sprk.unspecced.searchPostsSkeleton", + SoSprkUnspeccedSearchStarterPacksSkeleton: + "so.sprk.unspecced.searchStarterPacksSkeleton", + SoSprkVideoDefs: "so.sprk.video.defs", + SoSprkVideoGetJobStatus: "so.sprk.video.getJobStatus", + SoSprkVideoGetUploadLimits: "so.sprk.video.getUploadLimits", + SoSprkVideoUploadVideo: "so.sprk.video.uploadVideo", +} as const; diff --git a/services/appview/lexicon/types/com/atproto/admin/defs.ts b/services/appview/lexicon/types/com/atproto/admin/defs.ts new file mode 100644 index 0000000..2842629 --- /dev/null +++ b/services/appview/lexicon/types/com/atproto/admin/defs.ts @@ -0,0 +1,102 @@ +/** + * GENERATED CODE - DO NOT MODIFY + */ +import { BlobRef, ValidationResult } from "@atproto/lexicon"; +import { CID } from "multiformats/cid"; +import { validate as _validate } from "../../../../lexicons"; +import { $Typed, is$typed as _is$typed, OmitKey } from "../../../../util"; +import type * as ComAtprotoServerDefs from "../server/defs.ts"; + +const is$typed = _is$typed, + validate = _validate; +const id = "com.atproto.admin.defs"; + +export interface StatusAttr { + $type?: "com.atproto.admin.defs#statusAttr"; + applied: boolean; + ref?: string; +} + +const hashStatusAttr = "statusAttr"; + +export function isStatusAttr(v: V) { + return is$typed(v, id, hashStatusAttr); +} + +export function validateStatusAttr(v: V) { + return validate(v, id, hashStatusAttr); +} + +export interface AccountView { + $type?: "com.atproto.admin.defs#accountView"; + did: string; + handle: string; + email?: string; + relatedRecords?: { [_ in string]: unknown }[]; + indexedAt: string; + invitedBy?: ComAtprotoServerDefs.InviteCode; + invites?: ComAtprotoServerDefs.InviteCode[]; + invitesDisabled?: boolean; + emailConfirmedAt?: string; + inviteNote?: string; + deactivatedAt?: string; + threatSignatures?: ThreatSignature[]; +} + +const hashAccountView = "accountView"; + +export function isAccountView(v: V) { + return is$typed(v, id, hashAccountView); +} + +export function validateAccountView(v: V) { + return validate(v, id, hashAccountView); +} + +export interface RepoRef { + $type?: "com.atproto.admin.defs#repoRef"; + did: string; +} + +const hashRepoRef = "repoRef"; + +export function isRepoRef(v: V) { + return is$typed(v, id, hashRepoRef); +} + +export function validateRepoRef(v: V) { + return validate(v, id, hashRepoRef); +} + +export interface RepoBlobRef { + $type?: "com.atproto.admin.defs#repoBlobRef"; + did: string; + cid: string; + recordUri?: string; +} + +const hashRepoBlobRef = "repoBlobRef"; + +export function isRepoBlobRef(v: V) { + return is$typed(v, id, hashRepoBlobRef); +} + +export function validateRepoBlobRef(v: V) { + return validate(v, id, hashRepoBlobRef); +} + +export interface ThreatSignature { + $type?: "com.atproto.admin.defs#threatSignature"; + property: string; + value: string; +} + +const hashThreatSignature = "threatSignature"; + +export function isThreatSignature(v: V) { + return is$typed(v, id, hashThreatSignature); +} + +export function validateThreatSignature(v: V) { + return validate(v, id, hashThreatSignature); +} diff --git a/services/appview/lexicon/types/com/atproto/admin/deleteAccount.ts b/services/appview/lexicon/types/com/atproto/admin/deleteAccount.ts new file mode 100644 index 0000000..f327aa0 --- /dev/null +++ b/services/appview/lexicon/types/com/atproto/admin/deleteAccount.ts @@ -0,0 +1,42 @@ +/** + * GENERATED CODE - DO NOT MODIFY + */ +import express from "npm:express"; +import { BlobRef, ValidationResult } from "@atproto/lexicon"; +import { CID } from "multiformats/cid"; +import { validate as _validate } from "../../../../lexicons"; +import { $Typed, is$typed as _is$typed, OmitKey } from "../../../../util"; +import { HandlerAuth, HandlerPipeThrough } from "@atproto/xrpc-server"; + +const is$typed = _is$typed, + validate = _validate; +const id = "com.atproto.admin.deleteAccount"; + +export interface QueryParams {} + +export interface InputSchema { + did: string; +} + +export interface HandlerInput { + encoding: "application/json"; + body: InputSchema; +} + +export interface HandlerError { + status: number; + message?: string; +} + +export type HandlerOutput = HandlerError | void; +export type HandlerReqCtx = { + auth: HA; + params: QueryParams; + input: HandlerInput; + req: express.Request; + res: express.Response; + resetRouteRateLimits: () => Promise; +}; +export type Handler = ( + ctx: HandlerReqCtx, +) => Promise | HandlerOutput; diff --git a/services/appview/lexicon/types/com/atproto/admin/disableAccountInvites.ts b/services/appview/lexicon/types/com/atproto/admin/disableAccountInvites.ts new file mode 100644 index 0000000..36909f4 --- /dev/null +++ b/services/appview/lexicon/types/com/atproto/admin/disableAccountInvites.ts @@ -0,0 +1,44 @@ +/** + * GENERATED CODE - DO NOT MODIFY + */ +import express from "express"; +import { BlobRef, ValidationResult } from "@atproto/lexicon"; +import { CID } from "multiformats/cid"; +import { validate as _validate } from "../../../../lexicons"; +import { $Typed, is$typed as _is$typed, OmitKey } from "../../../../util"; +import { HandlerAuth, HandlerPipeThrough } from "@atproto/xrpc-server"; + +const is$typed = _is$typed, + validate = _validate; +const id = "com.atproto.admin.disableAccountInvites"; + +export interface QueryParams {} + +export interface InputSchema { + account: string; + /** Optional reason for disabled invites. */ + note?: string; +} + +export interface HandlerInput { + encoding: "application/json"; + body: InputSchema; +} + +export interface HandlerError { + status: number; + message?: string; +} + +export type HandlerOutput = HandlerError | void; +export type HandlerReqCtx = { + auth: HA; + params: QueryParams; + input: HandlerInput; + req: express.Request; + res: express.Response; + resetRouteRateLimits: () => Promise; +}; +export type Handler = ( + ctx: HandlerReqCtx, +) => Promise | HandlerOutput; diff --git a/services/appview/lexicon/types/com/atproto/admin/disableInviteCodes.ts b/services/appview/lexicon/types/com/atproto/admin/disableInviteCodes.ts new file mode 100644 index 0000000..ae2c6f2 --- /dev/null +++ b/services/appview/lexicon/types/com/atproto/admin/disableInviteCodes.ts @@ -0,0 +1,43 @@ +/** + * GENERATED CODE - DO NOT MODIFY + */ +import express from "express"; +import { BlobRef, ValidationResult } from "@atproto/lexicon"; +import { CID } from "multiformats/cid"; +import { validate as _validate } from "../../../../lexicons"; +import { $Typed, is$typed as _is$typed, OmitKey } from "../../../../util"; +import { HandlerAuth, HandlerPipeThrough } from "@atproto/xrpc-server"; + +const is$typed = _is$typed, + validate = _validate; +const id = "com.atproto.admin.disableInviteCodes"; + +export interface QueryParams {} + +export interface InputSchema { + codes?: string[]; + accounts?: string[]; +} + +export interface HandlerInput { + encoding: "application/json"; + body: InputSchema; +} + +export interface HandlerError { + status: number; + message?: string; +} + +export type HandlerOutput = HandlerError | void; +export type HandlerReqCtx = { + auth: HA; + params: QueryParams; + input: HandlerInput; + req: express.Request; + res: express.Response; + resetRouteRateLimits: () => Promise; +}; +export type Handler = ( + ctx: HandlerReqCtx, +) => Promise | HandlerOutput; diff --git a/services/appview/lexicon/types/com/atproto/admin/enableAccountInvites.ts b/services/appview/lexicon/types/com/atproto/admin/enableAccountInvites.ts new file mode 100644 index 0000000..9984601 --- /dev/null +++ b/services/appview/lexicon/types/com/atproto/admin/enableAccountInvites.ts @@ -0,0 +1,44 @@ +/** + * GENERATED CODE - DO NOT MODIFY + */ +import express from "express"; +import { BlobRef, ValidationResult } from "@atproto/lexicon"; +import { CID } from "multiformats/cid"; +import { validate as _validate } from "../../../../lexicons"; +import { $Typed, is$typed as _is$typed, OmitKey } from "../../../../util"; +import { HandlerAuth, HandlerPipeThrough } from "@atproto/xrpc-server"; + +const is$typed = _is$typed, + validate = _validate; +const id = "com.atproto.admin.enableAccountInvites"; + +export interface QueryParams {} + +export interface InputSchema { + account: string; + /** Optional reason for enabled invites. */ + note?: string; +} + +export interface HandlerInput { + encoding: "application/json"; + body: InputSchema; +} + +export interface HandlerError { + status: number; + message?: string; +} + +export type HandlerOutput = HandlerError | void; +export type HandlerReqCtx = { + auth: HA; + params: QueryParams; + input: HandlerInput; + req: express.Request; + res: express.Response; + resetRouteRateLimits: () => Promise; +}; +export type Handler = ( + ctx: HandlerReqCtx, +) => Promise | HandlerOutput; diff --git a/services/appview/lexicon/types/com/atproto/admin/getAccountInfo.ts b/services/appview/lexicon/types/com/atproto/admin/getAccountInfo.ts new file mode 100644 index 0000000..30397fc --- /dev/null +++ b/services/appview/lexicon/types/com/atproto/admin/getAccountInfo.ts @@ -0,0 +1,46 @@ +/** + * GENERATED CODE - DO NOT MODIFY + */ +import express from "express"; +import { BlobRef, ValidationResult } from "@atproto/lexicon"; +import { CID } from "multiformats/cid"; +import { validate as _validate } from "../../../../lexicons"; +import { $Typed, is$typed as _is$typed, OmitKey } from "../../../../util"; +import { HandlerAuth, HandlerPipeThrough } from "@atproto/xrpc-server"; +import type * as ComAtprotoAdminDefs from "./defs.ts"; + +const is$typed = _is$typed, + validate = _validate; +const id = "com.atproto.admin.getAccountInfo"; + +export interface QueryParams { + did: string; +} + +export type InputSchema = undefined; +export type OutputSchema = ComAtprotoAdminDefs.AccountView; +export type HandlerInput = undefined; + +export interface HandlerSuccess { + encoding: "application/json"; + body: OutputSchema; + headers?: { [key: string]: string }; +} + +export interface HandlerError { + status: number; + message?: string; +} + +export type HandlerOutput = HandlerError | HandlerSuccess | HandlerPipeThrough; +export type HandlerReqCtx = { + auth: HA; + params: QueryParams; + input: HandlerInput; + req: express.Request; + res: express.Response; + resetRouteRateLimits: () => Promise; +}; +export type Handler = ( + ctx: HandlerReqCtx, +) => Promise | HandlerOutput; diff --git a/services/appview/lexicon/types/com/atproto/admin/getAccountInfos.ts b/services/appview/lexicon/types/com/atproto/admin/getAccountInfos.ts new file mode 100644 index 0000000..5644e14 --- /dev/null +++ b/services/appview/lexicon/types/com/atproto/admin/getAccountInfos.ts @@ -0,0 +1,50 @@ +/** + * GENERATED CODE - DO NOT MODIFY + */ +import express from "express"; +import { BlobRef, ValidationResult } from "@atproto/lexicon"; +import { CID } from "multiformats/cid"; +import { validate as _validate } from "../../../../lexicons"; +import { $Typed, is$typed as _is$typed, OmitKey } from "../../../../util"; +import { HandlerAuth, HandlerPipeThrough } from "@atproto/xrpc-server"; +import type * as ComAtprotoAdminDefs from "./defs.ts"; + +const is$typed = _is$typed, + validate = _validate; +const id = "com.atproto.admin.getAccountInfos"; + +export interface QueryParams { + dids: string[]; +} + +export type InputSchema = undefined; + +export interface OutputSchema { + infos: ComAtprotoAdminDefs.AccountView[]; +} + +export type HandlerInput = undefined; + +export interface HandlerSuccess { + encoding: "application/json"; + body: OutputSchema; + headers?: { [key: string]: string }; +} + +export interface HandlerError { + status: number; + message?: string; +} + +export type HandlerOutput = HandlerError | HandlerSuccess | HandlerPipeThrough; +export type HandlerReqCtx = { + auth: HA; + params: QueryParams; + input: HandlerInput; + req: express.Request; + res: express.Response; + resetRouteRateLimits: () => Promise; +}; +export type Handler = ( + ctx: HandlerReqCtx, +) => Promise | HandlerOutput; diff --git a/services/appview/lexicon/types/com/atproto/admin/getInviteCodes.ts b/services/appview/lexicon/types/com/atproto/admin/getInviteCodes.ts new file mode 100644 index 0000000..0ec4427 --- /dev/null +++ b/services/appview/lexicon/types/com/atproto/admin/getInviteCodes.ts @@ -0,0 +1,53 @@ +/** + * GENERATED CODE - DO NOT MODIFY + */ +import express from "express"; +import { BlobRef, ValidationResult } from "@atproto/lexicon"; +import { CID } from "multiformats/cid"; +import { validate as _validate } from "../../../../lexicons"; +import { $Typed, is$typed as _is$typed, OmitKey } from "../../../../util"; +import { HandlerAuth, HandlerPipeThrough } from "@atproto/xrpc-server"; +import type * as ComAtprotoServerDefs from "../server/defs.ts"; + +const is$typed = _is$typed, + validate = _validate; +const id = "com.atproto.admin.getInviteCodes"; + +export interface QueryParams { + sort: "recent" | "usage" | (string & {}); + limit: number; + cursor?: string; +} + +export type InputSchema = undefined; + +export interface OutputSchema { + cursor?: string; + codes: ComAtprotoServerDefs.InviteCode[]; +} + +export type HandlerInput = undefined; + +export interface HandlerSuccess { + encoding: "application/json"; + body: OutputSchema; + headers?: { [key: string]: string }; +} + +export interface HandlerError { + status: number; + message?: string; +} + +export type HandlerOutput = HandlerError | HandlerSuccess | HandlerPipeThrough; +export type HandlerReqCtx = { + auth: HA; + params: QueryParams; + input: HandlerInput; + req: express.Request; + res: express.Response; + resetRouteRateLimits: () => Promise; +}; +export type Handler = ( + ctx: HandlerReqCtx, +) => Promise | HandlerOutput; diff --git a/services/appview/lexicon/types/com/atproto/admin/getSubjectStatus.ts b/services/appview/lexicon/types/com/atproto/admin/getSubjectStatus.ts new file mode 100644 index 0000000..8af0d9f --- /dev/null +++ b/services/appview/lexicon/types/com/atproto/admin/getSubjectStatus.ts @@ -0,0 +1,59 @@ +/** + * GENERATED CODE - DO NOT MODIFY + */ +import express from "express"; +import { BlobRef, ValidationResult } from "@atproto/lexicon"; +import { CID } from "multiformats/cid"; +import { validate as _validate } from "../../../../lexicons"; +import { $Typed, is$typed as _is$typed, OmitKey } from "../../../../util"; +import { HandlerAuth, HandlerPipeThrough } from "@atproto/xrpc-server"; +import type * as ComAtprotoAdminDefs from "./defs.ts"; +import type * as ComAtprotoRepoStrongRef from "../repo/strongRef.ts"; + +const is$typed = _is$typed, + validate = _validate; +const id = "com.atproto.admin.getSubjectStatus"; + +export interface QueryParams { + did?: string; + uri?: string; + blob?: string; +} + +export type InputSchema = undefined; + +export interface OutputSchema { + subject: + | $Typed + | $Typed + | $Typed + | { $type: string }; + takedown?: ComAtprotoAdminDefs.StatusAttr; + deactivated?: ComAtprotoAdminDefs.StatusAttr; +} + +export type HandlerInput = undefined; + +export interface HandlerSuccess { + encoding: "application/json"; + body: OutputSchema; + headers?: { [key: string]: string }; +} + +export interface HandlerError { + status: number; + message?: string; +} + +export type HandlerOutput = HandlerError | HandlerSuccess | HandlerPipeThrough; +export type HandlerReqCtx = { + auth: HA; + params: QueryParams; + input: HandlerInput; + req: express.Request; + res: express.Response; + resetRouteRateLimits: () => Promise; +}; +export type Handler = ( + ctx: HandlerReqCtx, +) => Promise | HandlerOutput; diff --git a/services/appview/lexicon/types/com/atproto/admin/searchAccounts.ts b/services/appview/lexicon/types/com/atproto/admin/searchAccounts.ts new file mode 100644 index 0000000..acb2ea0 --- /dev/null +++ b/services/appview/lexicon/types/com/atproto/admin/searchAccounts.ts @@ -0,0 +1,53 @@ +/** + * GENERATED CODE - DO NOT MODIFY + */ +import express from "express"; +import { BlobRef, ValidationResult } from "@atproto/lexicon"; +import { CID } from "multiformats/cid"; +import { validate as _validate } from "../../../../lexicons"; +import { $Typed, is$typed as _is$typed, OmitKey } from "../../../../util"; +import { HandlerAuth, HandlerPipeThrough } from "@atproto/xrpc-server"; +import type * as ComAtprotoAdminDefs from "./defs.ts"; + +const is$typed = _is$typed, + validate = _validate; +const id = "com.atproto.admin.searchAccounts"; + +export interface QueryParams { + email?: string; + cursor?: string; + limit: number; +} + +export type InputSchema = undefined; + +export interface OutputSchema { + cursor?: string; + accounts: ComAtprotoAdminDefs.AccountView[]; +} + +export type HandlerInput = undefined; + +export interface HandlerSuccess { + encoding: "application/json"; + body: OutputSchema; + headers?: { [key: string]: string }; +} + +export interface HandlerError { + status: number; + message?: string; +} + +export type HandlerOutput = HandlerError | HandlerSuccess | HandlerPipeThrough; +export type HandlerReqCtx = { + auth: HA; + params: QueryParams; + input: HandlerInput; + req: express.Request; + res: express.Response; + resetRouteRateLimits: () => Promise; +}; +export type Handler = ( + ctx: HandlerReqCtx, +) => Promise | HandlerOutput; diff --git a/services/appview/lexicon/types/com/atproto/admin/sendEmail.ts b/services/appview/lexicon/types/com/atproto/admin/sendEmail.ts new file mode 100644 index 0000000..a1aceaf --- /dev/null +++ b/services/appview/lexicon/types/com/atproto/admin/sendEmail.ts @@ -0,0 +1,57 @@ +/** + * GENERATED CODE - DO NOT MODIFY + */ +import express from "express"; +import { BlobRef, ValidationResult } from "@atproto/lexicon"; +import { CID } from "multiformats/cid"; +import { validate as _validate } from "../../../../lexicons"; +import { $Typed, is$typed as _is$typed, OmitKey } from "../../../../util"; +import { HandlerAuth, HandlerPipeThrough } from "@atproto/xrpc-server"; + +const is$typed = _is$typed, + validate = _validate; +const id = "com.atproto.admin.sendEmail"; + +export interface QueryParams {} + +export interface InputSchema { + recipientDid: string; + content: string; + subject?: string; + senderDid: string; + /** Additional comment by the sender that won't be used in the email itself but helpful to provide more context for moderators/reviewers */ + comment?: string; +} + +export interface OutputSchema { + sent: boolean; +} + +export interface HandlerInput { + encoding: "application/json"; + body: InputSchema; +} + +export interface HandlerSuccess { + encoding: "application/json"; + body: OutputSchema; + headers?: { [key: string]: string }; +} + +export interface HandlerError { + status: number; + message?: string; +} + +export type HandlerOutput = HandlerError | HandlerSuccess | HandlerPipeThrough; +export type HandlerReqCtx = { + auth: HA; + params: QueryParams; + input: HandlerInput; + req: express.Request; + res: express.Response; + resetRouteRateLimits: () => Promise; +}; +export type Handler = ( + ctx: HandlerReqCtx, +) => Promise | HandlerOutput; diff --git a/services/appview/lexicon/types/com/atproto/admin/updateAccountEmail.ts b/services/appview/lexicon/types/com/atproto/admin/updateAccountEmail.ts new file mode 100644 index 0000000..a89da81 --- /dev/null +++ b/services/appview/lexicon/types/com/atproto/admin/updateAccountEmail.ts @@ -0,0 +1,44 @@ +/** + * GENERATED CODE - DO NOT MODIFY + */ +import express from "express"; +import { BlobRef, ValidationResult } from "@atproto/lexicon"; +import { CID } from "multiformats/cid"; +import { validate as _validate } from "../../../../lexicons"; +import { $Typed, is$typed as _is$typed, OmitKey } from "../../../../util"; +import { HandlerAuth, HandlerPipeThrough } from "@atproto/xrpc-server"; + +const is$typed = _is$typed, + validate = _validate; +const id = "com.atproto.admin.updateAccountEmail"; + +export interface QueryParams {} + +export interface InputSchema { + /** The handle or DID of the repo. */ + account: string; + email: string; +} + +export interface HandlerInput { + encoding: "application/json"; + body: InputSchema; +} + +export interface HandlerError { + status: number; + message?: string; +} + +export type HandlerOutput = HandlerError | void; +export type HandlerReqCtx = { + auth: HA; + params: QueryParams; + input: HandlerInput; + req: express.Request; + res: express.Response; + resetRouteRateLimits: () => Promise; +}; +export type Handler = ( + ctx: HandlerReqCtx, +) => Promise | HandlerOutput; diff --git a/services/appview/lexicon/types/com/atproto/admin/updateAccountHandle.ts b/services/appview/lexicon/types/com/atproto/admin/updateAccountHandle.ts new file mode 100644 index 0000000..28c7b07 --- /dev/null +++ b/services/appview/lexicon/types/com/atproto/admin/updateAccountHandle.ts @@ -0,0 +1,43 @@ +/** + * GENERATED CODE - DO NOT MODIFY + */ +import express from "express"; +import { BlobRef, ValidationResult } from "@atproto/lexicon"; +import { CID } from "multiformats/cid"; +import { validate as _validate } from "../../../../lexicons"; +import { $Typed, is$typed as _is$typed, OmitKey } from "../../../../util"; +import { HandlerAuth, HandlerPipeThrough } from "@atproto/xrpc-server"; + +const is$typed = _is$typed, + validate = _validate; +const id = "com.atproto.admin.updateAccountHandle"; + +export interface QueryParams {} + +export interface InputSchema { + did: string; + handle: string; +} + +export interface HandlerInput { + encoding: "application/json"; + body: InputSchema; +} + +export interface HandlerError { + status: number; + message?: string; +} + +export type HandlerOutput = HandlerError | void; +export type HandlerReqCtx = { + auth: HA; + params: QueryParams; + input: HandlerInput; + req: express.Request; + res: express.Response; + resetRouteRateLimits: () => Promise; +}; +export type Handler = ( + ctx: HandlerReqCtx, +) => Promise | HandlerOutput; diff --git a/services/appview/lexicon/types/com/atproto/admin/updateAccountPassword.ts b/services/appview/lexicon/types/com/atproto/admin/updateAccountPassword.ts new file mode 100644 index 0000000..8d702b6 --- /dev/null +++ b/services/appview/lexicon/types/com/atproto/admin/updateAccountPassword.ts @@ -0,0 +1,43 @@ +/** + * GENERATED CODE - DO NOT MODIFY + */ +import express from "express"; +import { BlobRef, ValidationResult } from "@atproto/lexicon"; +import { CID } from "multiformats/cid"; +import { validate as _validate } from "../../../../lexicons"; +import { $Typed, is$typed as _is$typed, OmitKey } from "../../../../util"; +import { HandlerAuth, HandlerPipeThrough } from "@atproto/xrpc-server"; + +const is$typed = _is$typed, + validate = _validate; +const id = "com.atproto.admin.updateAccountPassword"; + +export interface QueryParams {} + +export interface InputSchema { + did: string; + password: string; +} + +export interface HandlerInput { + encoding: "application/json"; + body: InputSchema; +} + +export interface HandlerError { + status: number; + message?: string; +} + +export type HandlerOutput = HandlerError | void; +export type HandlerReqCtx = { + auth: HA; + params: QueryParams; + input: HandlerInput; + req: express.Request; + res: express.Response; + resetRouteRateLimits: () => Promise; +}; +export type Handler = ( + ctx: HandlerReqCtx, +) => Promise | HandlerOutput; diff --git a/services/appview/lexicon/types/com/atproto/admin/updateSubjectStatus.ts b/services/appview/lexicon/types/com/atproto/admin/updateSubjectStatus.ts new file mode 100644 index 0000000..413bcee --- /dev/null +++ b/services/appview/lexicon/types/com/atproto/admin/updateSubjectStatus.ts @@ -0,0 +1,65 @@ +/** + * GENERATED CODE - DO NOT MODIFY + */ +import express from "express"; +import { BlobRef, ValidationResult } from "@atproto/lexicon"; +import { CID } from "multiformats/cid"; +import { validate as _validate } from "../../../../lexicons"; +import { $Typed, is$typed as _is$typed, OmitKey } from "../../../../util"; +import { HandlerAuth, HandlerPipeThrough } from "@atproto/xrpc-server"; +import type * as ComAtprotoAdminDefs from "./defs.ts"; +import type * as ComAtprotoRepoStrongRef from "../repo/strongRef.ts"; + +const is$typed = _is$typed, + validate = _validate; +const id = "com.atproto.admin.updateSubjectStatus"; + +export interface QueryParams {} + +export interface InputSchema { + subject: + | $Typed + | $Typed + | $Typed + | { $type: string }; + takedown?: ComAtprotoAdminDefs.StatusAttr; + deactivated?: ComAtprotoAdminDefs.StatusAttr; +} + +export interface OutputSchema { + subject: + | $Typed + | $Typed + | $Typed + | { $type: string }; + takedown?: ComAtprotoAdminDefs.StatusAttr; +} + +export interface HandlerInput { + encoding: "application/json"; + body: InputSchema; +} + +export interface HandlerSuccess { + encoding: "application/json"; + body: OutputSchema; + headers?: { [key: string]: string }; +} + +export interface HandlerError { + status: number; + message?: string; +} + +export type HandlerOutput = HandlerError | HandlerSuccess | HandlerPipeThrough; +export type HandlerReqCtx = { + auth: HA; + params: QueryParams; + input: HandlerInput; + req: express.Request; + res: express.Response; + resetRouteRateLimits: () => Promise; +}; +export type Handler = ( + ctx: HandlerReqCtx, +) => Promise | HandlerOutput; diff --git a/services/appview/lexicon/types/com/atproto/identity/getRecommendedDidCredentials.ts b/services/appview/lexicon/types/com/atproto/identity/getRecommendedDidCredentials.ts new file mode 100644 index 0000000..e6fe74c --- /dev/null +++ b/services/appview/lexicon/types/com/atproto/identity/getRecommendedDidCredentials.ts @@ -0,0 +1,51 @@ +/** + * GENERATED CODE - DO NOT MODIFY + */ +import express from "express"; +import { BlobRef, ValidationResult } from "@atproto/lexicon"; +import { CID } from "multiformats/cid"; +import { validate as _validate } from "../../../../lexicons"; +import { $Typed, is$typed as _is$typed, OmitKey } from "../../../../util"; +import { HandlerAuth, HandlerPipeThrough } from "@atproto/xrpc-server"; + +const is$typed = _is$typed, + validate = _validate; +const id = "com.atproto.identity.getRecommendedDidCredentials"; + +export interface QueryParams {} + +export type InputSchema = undefined; + +export interface OutputSchema { + /** Recommended rotation keys for PLC dids. Should be undefined (or ignored) for did:webs. */ + rotationKeys?: string[]; + alsoKnownAs?: string[]; + verificationMethods?: { [_ in string]: unknown }; + services?: { [_ in string]: unknown }; +} + +export type HandlerInput = undefined; + +export interface HandlerSuccess { + encoding: "application/json"; + body: OutputSchema; + headers?: { [key: string]: string }; +} + +export interface HandlerError { + status: number; + message?: string; +} + +export type HandlerOutput = HandlerError | HandlerSuccess | HandlerPipeThrough; +export type HandlerReqCtx = { + auth: HA; + params: QueryParams; + input: HandlerInput; + req: express.Request; + res: express.Response; + resetRouteRateLimits: () => Promise; +}; +export type Handler = ( + ctx: HandlerReqCtx, +) => Promise | HandlerOutput; diff --git a/services/appview/lexicon/types/com/atproto/identity/requestPlcOperationSignature.ts b/services/appview/lexicon/types/com/atproto/identity/requestPlcOperationSignature.ts new file mode 100644 index 0000000..fe16dd6 --- /dev/null +++ b/services/appview/lexicon/types/com/atproto/identity/requestPlcOperationSignature.ts @@ -0,0 +1,36 @@ +/** + * GENERATED CODE - DO NOT MODIFY + */ +import express from "express"; +import { BlobRef, ValidationResult } from "@atproto/lexicon"; +import { CID } from "multiformats/cid"; +import { validate as _validate } from "../../../../lexicons"; +import { $Typed, is$typed as _is$typed, OmitKey } from "../../../../util"; +import { HandlerAuth, HandlerPipeThrough } from "@atproto/xrpc-server"; + +const is$typed = _is$typed, + validate = _validate; +const id = "com.atproto.identity.requestPlcOperationSignature"; + +export interface QueryParams {} + +export type InputSchema = undefined; +export type HandlerInput = undefined; + +export interface HandlerError { + status: number; + message?: string; +} + +export type HandlerOutput = HandlerError | void; +export type HandlerReqCtx = { + auth: HA; + params: QueryParams; + input: HandlerInput; + req: express.Request; + res: express.Response; + resetRouteRateLimits: () => Promise; +}; +export type Handler = ( + ctx: HandlerReqCtx, +) => Promise | HandlerOutput; diff --git a/services/appview/lexicon/types/com/atproto/identity/resolveHandle.ts b/services/appview/lexicon/types/com/atproto/identity/resolveHandle.ts new file mode 100644 index 0000000..27da76c --- /dev/null +++ b/services/appview/lexicon/types/com/atproto/identity/resolveHandle.ts @@ -0,0 +1,50 @@ +/** + * GENERATED CODE - DO NOT MODIFY + */ +import express from "express"; +import { BlobRef, ValidationResult } from "@atproto/lexicon"; +import { CID } from "multiformats/cid"; +import { validate as _validate } from "../../../../lexicons"; +import { $Typed, is$typed as _is$typed, OmitKey } from "../../../../util"; +import { HandlerAuth, HandlerPipeThrough } from "@atproto/xrpc-server"; + +const is$typed = _is$typed, + validate = _validate; +const id = "com.atproto.identity.resolveHandle"; + +export interface QueryParams { + /** The handle to resolve. */ + handle: string; +} + +export type InputSchema = undefined; + +export interface OutputSchema { + did: string; +} + +export type HandlerInput = undefined; + +export interface HandlerSuccess { + encoding: "application/json"; + body: OutputSchema; + headers?: { [key: string]: string }; +} + +export interface HandlerError { + status: number; + message?: string; +} + +export type HandlerOutput = HandlerError | HandlerSuccess | HandlerPipeThrough; +export type HandlerReqCtx = { + auth: HA; + params: QueryParams; + input: HandlerInput; + req: express.Request; + res: express.Response; + resetRouteRateLimits: () => Promise; +}; +export type Handler = ( + ctx: HandlerReqCtx, +) => Promise | HandlerOutput; diff --git a/services/appview/lexicon/types/com/atproto/identity/signPlcOperation.ts b/services/appview/lexicon/types/com/atproto/identity/signPlcOperation.ts new file mode 100644 index 0000000..5d3c7c1 --- /dev/null +++ b/services/appview/lexicon/types/com/atproto/identity/signPlcOperation.ts @@ -0,0 +1,58 @@ +/** + * GENERATED CODE - DO NOT MODIFY + */ +import express from "express"; +import { BlobRef, ValidationResult } from "@atproto/lexicon"; +import { CID } from "multiformats/cid"; +import { validate as _validate } from "../../../../lexicons"; +import { $Typed, is$typed as _is$typed, OmitKey } from "../../../../util"; +import { HandlerAuth, HandlerPipeThrough } from "@atproto/xrpc-server"; + +const is$typed = _is$typed, + validate = _validate; +const id = "com.atproto.identity.signPlcOperation"; + +export interface QueryParams {} + +export interface InputSchema { + /** A token received through com.atproto.identity.requestPlcOperationSignature */ + token?: string; + rotationKeys?: string[]; + alsoKnownAs?: string[]; + verificationMethods?: { [_ in string]: unknown }; + services?: { [_ in string]: unknown }; +} + +export interface OutputSchema { + /** A signed DID PLC operation. */ + operation: { [_ in string]: unknown }; +} + +export interface HandlerInput { + encoding: "application/json"; + body: InputSchema; +} + +export interface HandlerSuccess { + encoding: "application/json"; + body: OutputSchema; + headers?: { [key: string]: string }; +} + +export interface HandlerError { + status: number; + message?: string; +} + +export type HandlerOutput = HandlerError | HandlerSuccess | HandlerPipeThrough; +export type HandlerReqCtx = { + auth: HA; + params: QueryParams; + input: HandlerInput; + req: express.Request; + res: express.Response; + resetRouteRateLimits: () => Promise; +}; +export type Handler = ( + ctx: HandlerReqCtx, +) => Promise | HandlerOutput; diff --git a/services/appview/lexicon/types/com/atproto/identity/submitPlcOperation.ts b/services/appview/lexicon/types/com/atproto/identity/submitPlcOperation.ts new file mode 100644 index 0000000..7b487ac --- /dev/null +++ b/services/appview/lexicon/types/com/atproto/identity/submitPlcOperation.ts @@ -0,0 +1,42 @@ +/** + * GENERATED CODE - DO NOT MODIFY + */ +import express from "express"; +import { BlobRef, ValidationResult } from "@atproto/lexicon"; +import { CID } from "multiformats/cid"; +import { validate as _validate } from "../../../../lexicons"; +import { $Typed, is$typed as _is$typed, OmitKey } from "../../../../util"; +import { HandlerAuth, HandlerPipeThrough } from "@atproto/xrpc-server"; + +const is$typed = _is$typed, + validate = _validate; +const id = "com.atproto.identity.submitPlcOperation"; + +export interface QueryParams {} + +export interface InputSchema { + operation: { [_ in string]: unknown }; +} + +export interface HandlerInput { + encoding: "application/json"; + body: InputSchema; +} + +export interface HandlerError { + status: number; + message?: string; +} + +export type HandlerOutput = HandlerError | void; +export type HandlerReqCtx = { + auth: HA; + params: QueryParams; + input: HandlerInput; + req: express.Request; + res: express.Response; + resetRouteRateLimits: () => Promise; +}; +export type Handler = ( + ctx: HandlerReqCtx, +) => Promise | HandlerOutput; diff --git a/services/appview/lexicon/types/com/atproto/identity/updateHandle.ts b/services/appview/lexicon/types/com/atproto/identity/updateHandle.ts new file mode 100644 index 0000000..082e3d5 --- /dev/null +++ b/services/appview/lexicon/types/com/atproto/identity/updateHandle.ts @@ -0,0 +1,43 @@ +/** + * GENERATED CODE - DO NOT MODIFY + */ +import express from "express"; +import { BlobRef, ValidationResult } from "@atproto/lexicon"; +import { CID } from "multiformats/cid"; +import { validate as _validate } from "../../../../lexicons"; +import { $Typed, is$typed as _is$typed, OmitKey } from "../../../../util"; +import { HandlerAuth, HandlerPipeThrough } from "@atproto/xrpc-server"; + +const is$typed = _is$typed, + validate = _validate; +const id = "com.atproto.identity.updateHandle"; + +export interface QueryParams {} + +export interface InputSchema { + /** The new handle. */ + handle: string; +} + +export interface HandlerInput { + encoding: "application/json"; + body: InputSchema; +} + +export interface HandlerError { + status: number; + message?: string; +} + +export type HandlerOutput = HandlerError | void; +export type HandlerReqCtx = { + auth: HA; + params: QueryParams; + input: HandlerInput; + req: express.Request; + res: express.Response; + resetRouteRateLimits: () => Promise; +}; +export type Handler = ( + ctx: HandlerReqCtx, +) => Promise | HandlerOutput; diff --git a/services/appview/src/lexicon/types/com/atproto/label/defs.ts b/services/appview/lexicon/types/com/atproto/label/defs.ts similarity index 60% rename from services/appview/src/lexicon/types/com/atproto/label/defs.ts rename to services/appview/lexicon/types/com/atproto/label/defs.ts index b5f75bf..4e38e73 100644 --- a/services/appview/src/lexicon/types/com/atproto/label/defs.ts +++ b/services/appview/lexicon/types/com/atproto/label/defs.ts @@ -1,122 +1,122 @@ /** * GENERATED CODE - DO NOT MODIFY */ -import { ValidationResult, BlobRef } from '@atproto/lexicon' -import { CID } from 'multiformats/cid' -import { validate as _validate } from '../../../../lexicons' -import { $Typed, is$typed as _is$typed, OmitKey } from '../../../../util' +import { BlobRef, ValidationResult } from "@atproto/lexicon"; +import { CID } from "multiformats/cid"; +import { validate as _validate } from "../../../../lexicons"; +import { $Typed, is$typed as _is$typed, OmitKey } from "../../../../util"; const is$typed = _is$typed, - validate = _validate -const id = 'com.atproto.label.defs' + validate = _validate; +const id = "com.atproto.label.defs"; /** Metadata tag on an atproto resource (eg, repo or record). */ export interface Label { - $type?: 'com.atproto.label.defs#label' + $type?: "com.atproto.label.defs#label"; /** The AT Protocol version of the label object. */ - ver?: number + ver?: number; /** DID of the actor who created this label. */ - src: string + src: string; /** AT URI of the record, repository (account), or other resource that this label applies to. */ - uri: string + uri: string; /** Optionally, CID specifying the specific version of 'uri' resource this label applies to. */ - cid?: string + cid?: string; /** The short string name of the value or type of this label. */ - val: string + val: string; /** If true, this is a negation label, overwriting a previous label. */ - neg?: boolean + neg?: boolean; /** Timestamp when this label was created. */ - cts: string + cts: string; /** Timestamp at which this label expires (no longer applies). */ - exp?: string + exp?: string; /** Signature of dag-cbor encoded label. */ - sig?: Uint8Array + sig?: Uint8Array; } -const hashLabel = 'label' +const hashLabel = "label"; export function isLabel(v: V) { - return is$typed(v, id, hashLabel) + return is$typed(v, id, hashLabel); } export function validateLabel(v: V) { - return validate