diff --git a/.gitignore b/.gitignore index 8a38445859..a9d64c266c 100644 --- a/.gitignore +++ b/.gitignore @@ -117,6 +117,9 @@ src/locale/locales/**/messages.js src/locale/locales/**/messages.mjs src/locale/locales/**/messages.ts +# generated lexicon schemas (pnpm lexicons:generate) +src/lexicons/ + # local builds *.apk *.aab diff --git a/.oxlintrc.json b/.oxlintrc.json index 63739f1f48..5868f74bb8 100644 --- a/.oxlintrc.json +++ b/.oxlintrc.json @@ -62,6 +62,7 @@ "bskyogcard/**", "src/locale/locales/_build/**", "src/locale/locales/**/*.js", + "src/lexicons/**", "*.e2e.ts", "*.e2e.tsx", "eslint.config.mjs", diff --git a/.prettierignore b/.prettierignore index afc71dbac1..be1658124a 100644 --- a/.prettierignore +++ b/.prettierignore @@ -18,6 +18,7 @@ android ios src/locale/locales +src/lexicons lib/react-compiler-runtime bskyweb/static coverage diff --git a/lexicons.json b/lexicons.json new file mode 100644 index 0000000000..52cd43df09 --- /dev/null +++ b/lexicons.json @@ -0,0 +1,1480 @@ +{ + "version": 1, + "lexicons": [ + "app.bsky.actor.defs", + "app.bsky.actor.getPreferences", + "app.bsky.actor.getProfile", + "app.bsky.actor.getProfiles", + "app.bsky.actor.getSuggestions", + "app.bsky.actor.profile", + "app.bsky.actor.putPreferences", + "app.bsky.actor.searchActors", + "app.bsky.actor.searchActorsTypeahead", + "app.bsky.actor.status", + "app.bsky.ageassurance.begin", + "app.bsky.ageassurance.defs", + "app.bsky.ageassurance.getConfig", + "app.bsky.ageassurance.getState", + "app.bsky.authCreatePosts", + "app.bsky.authDeleteContent", + "app.bsky.authFullApp", + "app.bsky.authManageFeedDeclarations", + "app.bsky.authManageLabelerService", + "app.bsky.authManageModeration", + "app.bsky.authManageNotifications", + "app.bsky.authManageProfile", + "app.bsky.authViewAll", + "app.bsky.bookmark.createBookmark", + "app.bsky.bookmark.defs", + "app.bsky.bookmark.deleteBookmark", + "app.bsky.bookmark.getBookmarks", + "app.bsky.contact.defs", + "app.bsky.contact.dismissMatch", + "app.bsky.contact.getMatches", + "app.bsky.contact.getSyncStatus", + "app.bsky.contact.importContacts", + "app.bsky.contact.removeData", + "app.bsky.contact.sendNotification", + "app.bsky.contact.startPhoneVerification", + "app.bsky.contact.verifyPhone", + "app.bsky.draft.createDraft", + "app.bsky.draft.defs", + "app.bsky.draft.deleteDraft", + "app.bsky.draft.getDrafts", + "app.bsky.draft.updateDraft", + "app.bsky.embed.defs", + "app.bsky.embed.external", + "app.bsky.embed.gallery", + "app.bsky.embed.getEmbedExternalView", + "app.bsky.embed.images", + "app.bsky.embed.record", + "app.bsky.embed.recordWithMedia", + "app.bsky.embed.video", + "app.bsky.feed.defs", + "app.bsky.feed.describeFeedGenerator", + "app.bsky.feed.generator", + "app.bsky.feed.getActorFeeds", + "app.bsky.feed.getActorLikes", + "app.bsky.feed.getAuthorFeed", + "app.bsky.feed.getFeed", + "app.bsky.feed.getFeedGenerator", + "app.bsky.feed.getFeedGenerators", + "app.bsky.feed.getFeedSkeleton", + "app.bsky.feed.getLikes", + "app.bsky.feed.getListFeed", + "app.bsky.feed.getPostThread", + "app.bsky.feed.getPosts", + "app.bsky.feed.getQuotes", + "app.bsky.feed.getRepostedBy", + "app.bsky.feed.getSuggestedFeeds", + "app.bsky.feed.getTimeline", + "app.bsky.feed.like", + "app.bsky.feed.post", + "app.bsky.feed.postgate", + "app.bsky.feed.repost", + "app.bsky.feed.searchPosts", + "app.bsky.feed.searchPostsV2", + "app.bsky.feed.sendInteractions", + "app.bsky.feed.threadgate", + "app.bsky.graph.block", + "app.bsky.graph.defs", + "app.bsky.graph.follow", + "app.bsky.graph.getActorStarterPacks", + "app.bsky.graph.getBlocks", + "app.bsky.graph.getFollowers", + "app.bsky.graph.getFollows", + "app.bsky.graph.getKnownFollowers", + "app.bsky.graph.getList", + "app.bsky.graph.getListBlocks", + "app.bsky.graph.getListMutes", + "app.bsky.graph.getLists", + "app.bsky.graph.getListsWithMembership", + "app.bsky.graph.getMutes", + "app.bsky.graph.getRelationships", + "app.bsky.graph.getStarterPack", + "app.bsky.graph.getStarterPacks", + "app.bsky.graph.getStarterPacksWithMembership", + "app.bsky.graph.getSuggestedFollowsByActor", + "app.bsky.graph.list", + "app.bsky.graph.listblock", + "app.bsky.graph.listitem", + "app.bsky.graph.muteActor", + "app.bsky.graph.muteActorList", + "app.bsky.graph.muteThread", + "app.bsky.graph.searchStarterPacks", + "app.bsky.graph.starterpack", + "app.bsky.graph.unmuteActor", + "app.bsky.graph.unmuteActorList", + "app.bsky.graph.unmuteThread", + "app.bsky.graph.verification", + "app.bsky.labeler.defs", + "app.bsky.labeler.getServices", + "app.bsky.labeler.service", + "app.bsky.notification.declaration", + "app.bsky.notification.defs", + "app.bsky.notification.getPreferences", + "app.bsky.notification.getUnreadCount", + "app.bsky.notification.listActivitySubscriptions", + "app.bsky.notification.listNotifications", + "app.bsky.notification.putActivitySubscription", + "app.bsky.notification.putPreferences", + "app.bsky.notification.putPreferencesV2", + "app.bsky.notification.registerPush", + "app.bsky.notification.unregisterPush", + "app.bsky.notification.updateSeen", + "app.bsky.richtext.facet", + "app.bsky.video.defs", + "app.bsky.video.getJobStatus", + "app.bsky.video.getUploadLimits", + "app.bsky.video.uploadVideo", + "chat.bsky.actor.declaration", + "chat.bsky.actor.defs", + "chat.bsky.actor.deleteAccount", + "chat.bsky.actor.exportAccountData", + "chat.bsky.actor.getStatus", + "chat.bsky.authFullChatClient", + "chat.bsky.convo.acceptConvo", + "chat.bsky.convo.addReaction", + "chat.bsky.convo.defs", + "chat.bsky.convo.deleteMessageForSelf", + "chat.bsky.convo.getConvo", + "chat.bsky.convo.getConvoAvailability", + "chat.bsky.convo.getConvoForMembers", + "chat.bsky.convo.getConvoMembers", + "chat.bsky.convo.getLog", + "chat.bsky.convo.getMessages", + "chat.bsky.convo.getUnreadCounts", + "chat.bsky.convo.leaveConvo", + "chat.bsky.convo.listConvoRequests", + "chat.bsky.convo.listConvos", + "chat.bsky.convo.lockConvo", + "chat.bsky.convo.muteConvo", + "chat.bsky.convo.removeReaction", + "chat.bsky.convo.sendMessage", + "chat.bsky.convo.sendMessageBatch", + "chat.bsky.convo.unlockConvo", + "chat.bsky.convo.unmuteConvo", + "chat.bsky.convo.updateAllRead", + "chat.bsky.convo.updateRead", + "chat.bsky.embed.joinLink", + "chat.bsky.group.addMembers", + "chat.bsky.group.approveJoinRequest", + "chat.bsky.group.createGroup", + "chat.bsky.group.createJoinLink", + "chat.bsky.group.defs", + "chat.bsky.group.disableJoinLink", + "chat.bsky.group.editGroup", + "chat.bsky.group.editJoinLink", + "chat.bsky.group.enableJoinLink", + "chat.bsky.group.getJoinLinkPreviews", + "chat.bsky.group.listJoinRequests", + "chat.bsky.group.listMutualGroups", + "chat.bsky.group.rejectJoinRequest", + "chat.bsky.group.removeMembers", + "chat.bsky.group.requestJoin", + "chat.bsky.group.updateJoinRequestsRead", + "chat.bsky.group.withdrawJoinRequest", + "chat.bsky.moderation.defs", + "chat.bsky.moderation.getActorMetadata", + "chat.bsky.moderation.getConvo", + "chat.bsky.moderation.getConvoMembers", + "chat.bsky.moderation.getConvos", + "chat.bsky.moderation.getMessageContext", + "chat.bsky.moderation.subscribeModEvents", + "chat.bsky.moderation.updateActorAccess", + "chat.bsky.notification.defs", + "chat.bsky.notification.getPreferences", + "chat.bsky.notification.putPreferences", + "com.atproto.admin.defs", + "com.atproto.admin.deleteAccount", + "com.atproto.admin.disableAccountInvites", + "com.atproto.admin.disableInviteCodes", + "com.atproto.admin.enableAccountInvites", + "com.atproto.admin.getAccountInfo", + "com.atproto.admin.getAccountInfos", + "com.atproto.admin.getInviteCodes", + "com.atproto.admin.getSubjectStatus", + "com.atproto.admin.searchAccounts", + "com.atproto.admin.sendEmail", + "com.atproto.admin.updateAccountEmail", + "com.atproto.admin.updateAccountHandle", + "com.atproto.admin.updateAccountPassword", + "com.atproto.admin.updateAccountSigningKey", + "com.atproto.admin.updateSubjectStatus", + "com.atproto.identity.defs", + "com.atproto.identity.getRecommendedDidCredentials", + "com.atproto.identity.refreshIdentity", + "com.atproto.identity.requestPlcOperationSignature", + "com.atproto.identity.resolveDid", + "com.atproto.identity.resolveHandle", + "com.atproto.identity.resolveIdentity", + "com.atproto.identity.signPlcOperation", + "com.atproto.identity.submitPlcOperation", + "com.atproto.identity.updateHandle", + "com.atproto.label.defs", + "com.atproto.label.queryLabels", + "com.atproto.label.subscribeLabels", + "com.atproto.lexicon.resolveLexicon", + "com.atproto.lexicon.schema", + "com.atproto.moderation.createReport", + "com.atproto.moderation.defs", + "com.atproto.repo.applyWrites", + "com.atproto.repo.createRecord", + "com.atproto.repo.defs", + "com.atproto.repo.deleteRecord", + "com.atproto.repo.describeRepo", + "com.atproto.repo.getRecord", + "com.atproto.repo.importRepo", + "com.atproto.repo.listMissingBlobs", + "com.atproto.repo.listRecords", + "com.atproto.repo.putRecord", + "com.atproto.repo.strongRef", + "com.atproto.repo.uploadBlob", + "com.atproto.server.activateAccount", + "com.atproto.server.checkAccountStatus", + "com.atproto.server.confirmEmail", + "com.atproto.server.createAccount", + "com.atproto.server.createAppPassword", + "com.atproto.server.createInviteCode", + "com.atproto.server.createInviteCodes", + "com.atproto.server.createSession", + "com.atproto.server.deactivateAccount", + "com.atproto.server.defs", + "com.atproto.server.deleteAccount", + "com.atproto.server.deleteSession", + "com.atproto.server.describeServer", + "com.atproto.server.getAccountInviteCodes", + "com.atproto.server.getServiceAuth", + "com.atproto.server.getSession", + "com.atproto.server.listAppPasswords", + "com.atproto.server.refreshSession", + "com.atproto.server.requestAccountDelete", + "com.atproto.server.requestEmailConfirmation", + "com.atproto.server.requestEmailUpdate", + "com.atproto.server.requestPasswordReset", + "com.atproto.server.reserveSigningKey", + "com.atproto.server.resetPassword", + "com.atproto.server.revokeAppPassword", + "com.atproto.server.updateEmail", + "com.atproto.sync.defs", + "com.atproto.sync.getBlob", + "com.atproto.sync.getBlocks", + "com.atproto.sync.getCheckout", + "com.atproto.sync.getHead", + "com.atproto.sync.getHostStatus", + "com.atproto.sync.getLatestCommit", + "com.atproto.sync.getRecord", + "com.atproto.sync.getRepo", + "com.atproto.sync.getRepoStatus", + "com.atproto.sync.listBlobs", + "com.atproto.sync.listHosts", + "com.atproto.sync.listRepos", + "com.atproto.sync.listReposByCollection", + "com.atproto.sync.notifyOfUpdate", + "com.atproto.sync.requestCrawl", + "com.atproto.sync.subscribeRepos", + "com.germnetwork.declaration" + ], + "resolutions": { + "app.bsky.actor.defs": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.actor.defs", + "cid": "bafyreihx4j3w2g2hduvnnbf6i53gma66m6xdiawri4rdrlm4vim3sxctui" + }, + "app.bsky.actor.getPreferences": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.actor.getPreferences", + "cid": "bafyreiaq3anjw7jtvejkiipghpjoxzlojh7ndqzgbaibsjfp3mxuote4cy" + }, + "app.bsky.actor.getProfile": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.actor.getProfile", + "cid": "bafyreibsxa3prdgatonsuzrwauswwufjoeu6swtlqfi3e443jauz5n6cpq" + }, + "app.bsky.actor.getProfiles": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.actor.getProfiles", + "cid": "bafyreieq3wuqinudxetx2esgscll4bs2qirixlgnml44eoc6t3lzhxapzi" + }, + "app.bsky.actor.getSuggestions": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.actor.getSuggestions", + "cid": "bafyreidjx3lzrtwr5tw7fhjcmetmcjo5grkfuv4kgxeqrlptgv5ss23aye" + }, + "app.bsky.actor.profile": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.actor.profile", + "cid": "bafyreihhja2ivgofo4myua5d4f5gs5hbw65sorfem5qz4i4rh726nt6tty" + }, + "app.bsky.actor.putPreferences": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.actor.putPreferences", + "cid": "bafyreifbuooovj4tcqwwyf2yk6lrur6vxt3jflwh3hplavy54tl3afl43q" + }, + "app.bsky.actor.searchActors": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.actor.searchActors", + "cid": "bafyreia2toqhys24ivgaqjjdcsjismmxim6u2htxrt5ja3ccko6yxisfh4" + }, + "app.bsky.actor.searchActorsTypeahead": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.actor.searchActorsTypeahead", + "cid": "bafyreia7swsmdptv3spdxmk76zyglilgxci7f33wz267ssbaryeqwkt7mq" + }, + "app.bsky.actor.status": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.actor.status", + "cid": "bafyreidb5e6wp3lcqel6ba2ybw5tzufk2tvf3q2hd5snxxc64rtyjpdcge" + }, + "app.bsky.ageassurance.begin": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.ageassurance.begin", + "cid": "bafyreig7dxyu2zoyswpwltt52eous3pairwwz6nqfni52ijpcovk45dtnm" + }, + "app.bsky.ageassurance.defs": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.ageassurance.defs", + "cid": "bafyreibb6kioccml6lypjq4zkaalhtpcxzqb2kcsjjhkdbffrcjz5chjbu" + }, + "app.bsky.ageassurance.getConfig": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.ageassurance.getConfig", + "cid": "bafyreihzz6ozmvlemgzg2tvkspe2v6jkjivuxmpi3iqlqd7om4nq7i5ix4" + }, + "app.bsky.ageassurance.getState": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.ageassurance.getState", + "cid": "bafyreidawbfn6qxjqb4bwsnqsoepmuu3tonf3qxyfzbrescycr5lwlnk64" + }, + "app.bsky.authCreatePosts": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.authCreatePosts", + "cid": "bafyreihuntnj3ptxgvyuhrbg5p6osumixvopym7qmhfozvvhak4eqwscfq" + }, + "app.bsky.authDeleteContent": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.authDeleteContent", + "cid": "bafyreicmy2l7fqjzsbomf3swolyvx6zq5tln27uvyktcsgy2thkmmjlhou" + }, + "app.bsky.authFullApp": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.authFullApp", + "cid": "bafyreif55zed3me4n27tq2bvr4wois4lbipqimqp5pwp5g7zh42edswrii" + }, + "app.bsky.authManageFeedDeclarations": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.authManageFeedDeclarations", + "cid": "bafyreihyxt6lpk3lgouscywc7mdpuovh5az5ef5ywpafsqn4m3yl67ba6e" + }, + "app.bsky.authManageLabelerService": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.authManageLabelerService", + "cid": "bafyreigkokm7ffi4ms35wcejb55a3mqm3aw7g4dgr3g6j62jdvqqol2il4" + }, + "app.bsky.authManageModeration": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.authManageModeration", + "cid": "bafyreih2inltobx4jhogu24aqicvassphwnsesxwvleaer5yvo2abveody" + }, + "app.bsky.authManageNotifications": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.authManageNotifications", + "cid": "bafyreihdmduvsbkc36pwtk4ddrt3wfrncckjebpyywkwci753vpptkpk5u" + }, + "app.bsky.authManageProfile": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.authManageProfile", + "cid": "bafyreidacpwqpmq5dg45j4aelggty3dz4tmoza37owmz2qf4cpj53ahdgi" + }, + "app.bsky.authViewAll": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.authViewAll", + "cid": "bafyreib4hrqpy2gitfik5f5useqh4zofbdzxwwwtelb72j45v33m7ohmcm" + }, + "app.bsky.bookmark.createBookmark": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.bookmark.createBookmark", + "cid": "bafyreihk6scljruozyf4l35npbgc47mjr73tecidtuxea6fo564wnnlzdu" + }, + "app.bsky.bookmark.defs": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.bookmark.defs", + "cid": "bafyreiepbe4x5lo7p4afmpvs2pdgrqxfwf27xotdqhe5zwnqaijzkottg4" + }, + "app.bsky.bookmark.deleteBookmark": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.bookmark.deleteBookmark", + "cid": "bafyreidczwvxtbygaoy55rdxlbhng5fil4tqvzgixvaab3egatn6xil65u" + }, + "app.bsky.bookmark.getBookmarks": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.bookmark.getBookmarks", + "cid": "bafyreiaojvosdp242g6atouzpresv4jjqeiylzym5zyhelomvytlagjn2a" + }, + "app.bsky.contact.defs": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.contact.defs", + "cid": "bafyreies6dsdiwsrhybcugwuffvcdajz4tevw5mtlrle3ougfhwmtp5atq" + }, + "app.bsky.contact.dismissMatch": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.contact.dismissMatch", + "cid": "bafyreiazs3fe2r5nztc3ngo6ezrnqenxcbtwoxdnw6p23nmwzvkfvbsksu" + }, + "app.bsky.contact.getMatches": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.contact.getMatches", + "cid": "bafyreihokzbbcj2dpxen6blnxkjsgalav3hmcir6tinv5i5qtefffzfnni" + }, + "app.bsky.contact.getSyncStatus": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.contact.getSyncStatus", + "cid": "bafyreidmc6ij7cmcjxcp5t2y3z3wxtfqfdekd63cqjoegnomotovgbbswy" + }, + "app.bsky.contact.importContacts": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.contact.importContacts", + "cid": "bafyreigjqugl5oij6zlaimb3opt7vktkbrg2uiu27ix2p5s7sg2cmrhezm" + }, + "app.bsky.contact.removeData": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.contact.removeData", + "cid": "bafyreiggfjngiol3qwsddbt7nwugjlfurssdf3z3uwix24n4jowvueej74" + }, + "app.bsky.contact.sendNotification": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.contact.sendNotification", + "cid": "bafyreihxlxdywrq476b2o7r2mcw6zbiyytb3xvgoptjthbmvndgmk4lnmy" + }, + "app.bsky.contact.startPhoneVerification": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.contact.startPhoneVerification", + "cid": "bafyreiedtsgyxrzhsnsjvmly23nl25rqyst2r5v6lgqjkm2f2ufocygfbu" + }, + "app.bsky.contact.verifyPhone": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.contact.verifyPhone", + "cid": "bafyreihcof5wnxic664y4zpllyhfpe43kpzjqu7tx6s4x6fvv5gofzl4pa" + }, + "app.bsky.draft.createDraft": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.draft.createDraft", + "cid": "bafyreieba6vqxiwmdh3a3zjugx2segpbgfn7caenu3a4hcm3vovrtjrl5u" + }, + "app.bsky.draft.defs": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.draft.defs", + "cid": "bafyreidlqwhrkuydvdi7beoeqmagdrxiaxv3l453wxghhhdcy6p3ftxpky" + }, + "app.bsky.draft.deleteDraft": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.draft.deleteDraft", + "cid": "bafyreighjzj26wkjj425rp6bxex2mxqmb6y2pubx2diggwnysgy2vmfin4" + }, + "app.bsky.draft.getDrafts": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.draft.getDrafts", + "cid": "bafyreidityubz53mtygge3jmiid2sfbqn6pxfuncbuy635qtbxudtcl67i" + }, + "app.bsky.draft.updateDraft": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.draft.updateDraft", + "cid": "bafyreih6hopk2m5xu4nhlyipfpvfymdwckrihy2bsmlf3eobs67uwtvg7a" + }, + "app.bsky.embed.defs": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.embed.defs", + "cid": "bafyreibvucawor4ulbdorsclmbqdmknh27smp6xgswnxrfwthpeymebcxu" + }, + "app.bsky.embed.external": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.embed.external", + "cid": "bafyreie5a6fqoiiio62sartttas66rr7dqdadakmfsbi4rcz5i7dv6uc7u" + }, + "app.bsky.embed.gallery": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.embed.gallery", + "cid": "bafyreiepstd4a7mqporspzs5hdfy6azgqcp27z45haiiwjcyvxd2pnhkoi" + }, + "app.bsky.embed.getEmbedExternalView": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.embed.getEmbedExternalView", + "cid": "bafyreiemnfnptqxnkvfvgih6ympflnum4ur3e6juplpyfnyeduixenttwy" + }, + "app.bsky.embed.images": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.embed.images", + "cid": "bafyreicujlvqddnkymznsffom2b767rjlhqqsmda22425nxmgykfumfofq" + }, + "app.bsky.embed.record": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.embed.record", + "cid": "bafyreiazjr7s6jgpzh2faldvlacyn24pe45e6v4ivi7wylyunahk4xrecm" + }, + "app.bsky.embed.recordWithMedia": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.embed.recordWithMedia", + "cid": "bafyreiefmmbj3sbvkn6skzhnpmc7ts5fodu3p6zd2bmuetq3ro5x7fuko4" + }, + "app.bsky.embed.video": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.embed.video", + "cid": "bafyreif3f3hruxofdjx4d726veodmewpu5yyu3ketut25jrvjuyn2mbemq" + }, + "app.bsky.feed.defs": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.feed.defs", + "cid": "bafyreicaltx56iwlybkmt3olgj3mtblpohbxa6fltab5mvkdyk3d5ba65a" + }, + "app.bsky.feed.describeFeedGenerator": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.feed.describeFeedGenerator", + "cid": "bafyreidm5fnbj57xya464srbub7sblzgstoruaew4gd2i3fl4kv6fmvrhe" + }, + "app.bsky.feed.generator": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.feed.generator", + "cid": "bafyreibd6guqn3kaov2ybgpwktimdrgkozyihwngcet5kbj7cfas5nvh5u" + }, + "app.bsky.feed.getActorFeeds": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.feed.getActorFeeds", + "cid": "bafyreiepzduedvuouygevxzqcnsiiddib42kh5lmfp4nw5yfipjglvfie4" + }, + "app.bsky.feed.getActorLikes": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.feed.getActorLikes", + "cid": "bafyreif6pyzzyona4b3fxcsnhbbji2gqgp5ubxrdasplczqespvioogyxi" + }, + "app.bsky.feed.getAuthorFeed": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.feed.getAuthorFeed", + "cid": "bafyreictayk7nnslodm4u6b6d32kmgdsa3d2rllyf5oo2ffgps7ergwmdi" + }, + "app.bsky.feed.getFeed": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.feed.getFeed", + "cid": "bafyreiaivdywiyoyaqmnh7a4knvaqeqsmh62und7gzyagxugpfrosn6p24" + }, + "app.bsky.feed.getFeedGenerator": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.feed.getFeedGenerator", + "cid": "bafyreihgis47dq7jqzmwd6douawhyfowwnq7ixzdmpzb3wm5hehw5atdn4" + }, + "app.bsky.feed.getFeedGenerators": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.feed.getFeedGenerators", + "cid": "bafyreie3a3cuwztmk6htohnjxfvmbx4qk62xa4gzhjcfo5uphkq3pbxylm" + }, + "app.bsky.feed.getFeedSkeleton": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.feed.getFeedSkeleton", + "cid": "bafyreihwjqh3bhmfth4o456nefg6tzogvhcmkrcplask7vr3yjbguonb6i" + }, + "app.bsky.feed.getLikes": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.feed.getLikes", + "cid": "bafyreieqarag3lnha55kiqwtuhwh3qq2pcdryzpx74m5nyyioao2em6s4u" + }, + "app.bsky.feed.getListFeed": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.feed.getListFeed", + "cid": "bafyreihocxy4qg3tpgl7vu3f2ekvzsqf6ipxcqo62ex22e3ybr3mijnaje" + }, + "app.bsky.feed.getPostThread": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.feed.getPostThread", + "cid": "bafyreifrbtqzngmes4twwgtfqad4vcolcof3o3oqdmsinhp6wwbt5l23lu" + }, + "app.bsky.feed.getPosts": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.feed.getPosts", + "cid": "bafyreihzuvfoowcisqdwj3dtay37oz3ctrgq5tmo2dkyaqehwixnp7ntqm" + }, + "app.bsky.feed.getQuotes": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.feed.getQuotes", + "cid": "bafyreib3rnm6qohjk22pg7orrspfvyenutcpdcxvhrfsfqac2g645fywvi" + }, + "app.bsky.feed.getRepostedBy": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.feed.getRepostedBy", + "cid": "bafyreih3cylvevc6tmmumtiooowetw7vhdapr254rc43rrky3phkn6hspm" + }, + "app.bsky.feed.getSuggestedFeeds": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.feed.getSuggestedFeeds", + "cid": "bafyreib3m3s2gmqn6yrvueqsavtabzpx47cad4ku45mb73nyoytpkregke" + }, + "app.bsky.feed.getTimeline": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.feed.getTimeline", + "cid": "bafyreih3xn5piyouk43nfodql45xapkytw5jfk27vqi47v5oqq3wda62iq" + }, + "app.bsky.feed.like": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.feed.like", + "cid": "bafyreifyyix2rt5rn7bsfl6wl6jxolalq3jgudyypc4tx7f6n3dsmfmype" + }, + "app.bsky.feed.post": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.feed.post", + "cid": "bafyreihaxwopec5qaq7o6wqjtngdhxgf25nlzskv4eot5hb6x6dhbkwgwe" + }, + "app.bsky.feed.postgate": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.feed.postgate", + "cid": "bafyreiafhomxs2vnlo5tgmxsgadugke6fxxgm5hgt6y62bs35fmdfkngv4" + }, + "app.bsky.feed.repost": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.feed.repost", + "cid": "bafyreigyqwr7qkyfwiiahjotxsm2wngvmupnvkla6znzsrti3r3x274pqu" + }, + "app.bsky.feed.searchPosts": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.feed.searchPosts", + "cid": "bafyreieyeblnzqdi25lrx7kzkzlzkxx2ehtpir267o67hchuczvw4itkoq" + }, + "app.bsky.feed.searchPostsV2": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.feed.searchPostsV2", + "cid": "bafyreieiif2m6k4xjii22jupbrzfwagtojcwxtnar7u6zml4pv6c6ct56u" + }, + "app.bsky.feed.sendInteractions": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.feed.sendInteractions", + "cid": "bafyreieylpwomikvymydjgcrewqgvis3glktzl36jg2jgeslejst4tbmsy" + }, + "app.bsky.feed.threadgate": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.feed.threadgate", + "cid": "bafyreihffhuqzvlvrkcuus2sdpnvw262y5t376tvy3jyjqtdys4ki2frw4" + }, + "app.bsky.graph.block": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.graph.block", + "cid": "bafyreieykrgqaau3nyp5iqbyn52x7pct3xcbf7yhiopnmxhvexbgocnad4" + }, + "app.bsky.graph.defs": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.graph.defs", + "cid": "bafyreidqyiw5cimihxfjm3ro5duqzpxis7ory7xoc6bjzxxuyxu2trmbru" + }, + "app.bsky.graph.follow": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.graph.follow", + "cid": "bafyreiefuady6oda7i6tkkegcdsy7nqqw634cdh4o445vkahptx66lcrhm" + }, + "app.bsky.graph.getActorStarterPacks": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.graph.getActorStarterPacks", + "cid": "bafyreiasnyjtdv3jz6xhagn47o7dnngap6td47r5zznlfpdyhwn7cndowa" + }, + "app.bsky.graph.getBlocks": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.graph.getBlocks", + "cid": "bafyreigtkyath5qetuw7rumxnk6rvouro73nsiak3owwtq6w274x6arcoy" + }, + "app.bsky.graph.getFollowers": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.graph.getFollowers", + "cid": "bafyreihf2jjv2tchwfe4xphzjifr6ig52rdnfg3gq5m6q4hevcmz2zib6y" + }, + "app.bsky.graph.getFollows": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.graph.getFollows", + "cid": "bafyreifih5zxzuhtazq6h2hzb2lfjnshyhgc2wy3mprhegqallprsi3mzy" + }, + "app.bsky.graph.getKnownFollowers": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.graph.getKnownFollowers", + "cid": "bafyreibafkvhouyhnt56mccmj5xnskalb32drctl3z3io6hrey6uxzjmyy" + }, + "app.bsky.graph.getList": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.graph.getList", + "cid": "bafyreidh64iu6nslfylwrzvrsun7aygiaoi3i2r4muxr7hum5godu5july" + }, + "app.bsky.graph.getListBlocks": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.graph.getListBlocks", + "cid": "bafyreifsyfuahh4nqwydapc5algqrduvwquoi6jflb7gd76jko6ar5b2ku" + }, + "app.bsky.graph.getListMutes": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.graph.getListMutes", + "cid": "bafyreicirczovoblatkzqnso3wr5m3wjhx6b5vvbg5d2tnmwufxvzkwium" + }, + "app.bsky.graph.getLists": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.graph.getLists", + "cid": "bafyreia37yzv3epfwrqghbnlde3jvp7iq7aj7cuevk65f5jb3ssmdvgyly" + }, + "app.bsky.graph.getListsWithMembership": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.graph.getListsWithMembership", + "cid": "bafyreiene2xutsyefxt6yh34dlqavxl4m4whavg2r5ewhavhppbg62chsm" + }, + "app.bsky.graph.getMutes": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.graph.getMutes", + "cid": "bafyreiaix3boqurslk374e5ynm6gb53miokbjwinpe2a3r5zxek32xcbcq" + }, + "app.bsky.graph.getRelationships": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.graph.getRelationships", + "cid": "bafyreieevwhibruwucybkmxaezcd6shzkw2hkljwq3kapf76vsjpluszue" + }, + "app.bsky.graph.getStarterPack": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.graph.getStarterPack", + "cid": "bafyreiaoo6if3vyexevxscxzoprf725xwzmrqsxwhpwiclqstwl2khio3u" + }, + "app.bsky.graph.getStarterPacks": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.graph.getStarterPacks", + "cid": "bafyreigcfkvpq4acfoorvk3vlf4cmtpftck6yaarqai46h6zfrsbe3a2cq" + }, + "app.bsky.graph.getStarterPacksWithMembership": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.graph.getStarterPacksWithMembership", + "cid": "bafyreicxovwgtk22uzqqjc355uafp6ltv45qe2ki6iefxqg5foqgh5mf4u" + }, + "app.bsky.graph.getSuggestedFollowsByActor": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.graph.getSuggestedFollowsByActor", + "cid": "bafyreifaroeykj6vnarisfbeoq4fqnpxvuw3qka7u4wj3z2ebwjd46orwa" + }, + "app.bsky.graph.list": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.graph.list", + "cid": "bafyreiax5fthedl4rn2heqsq2qkopdmxnxgw5o7csh7lm5juncbcksxagy" + }, + "app.bsky.graph.listblock": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.graph.listblock", + "cid": "bafyreiatgse2ljebx2we3rxssj2z73sludiiiv7jkebd6wfpjlg7szos2a" + }, + "app.bsky.graph.listitem": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.graph.listitem", + "cid": "bafyreidagbra7spspooscwpzs5xjzqmo7rrsgyntaezhyveoednhmqud7y" + }, + "app.bsky.graph.muteActor": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.graph.muteActor", + "cid": "bafyreidoakcqhuf52ww5kcfsu2ar7tgxhz3yu2ifblgou2harv5ei5ay7q" + }, + "app.bsky.graph.muteActorList": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.graph.muteActorList", + "cid": "bafyreiblj76uzkizlmjfsms3m2pxxhqp4rctqdgjmzzjm6qtqkelbihq24" + }, + "app.bsky.graph.muteThread": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.graph.muteThread", + "cid": "bafyreibp7yqwkx5anwxj2sg6qlhy2whp4wnuzytyi2iot73xs4osu277tu" + }, + "app.bsky.graph.searchStarterPacks": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.graph.searchStarterPacks", + "cid": "bafyreiccilccjcf6owlhgwu742ipbi5xfooa4aolkg6cuhnnplgyfveel4" + }, + "app.bsky.graph.starterpack": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.graph.starterpack", + "cid": "bafyreih6wyvcj4gbkywomzbgj5rx742wz6qewew75xne43d4wld37u3ena" + }, + "app.bsky.graph.unmuteActor": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.graph.unmuteActor", + "cid": "bafyreidfrq6eeuqhrnfh2yzbg7t4vbr52wlwqpjs54knswzc7dwsanoshe" + }, + "app.bsky.graph.unmuteActorList": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.graph.unmuteActorList", + "cid": "bafyreibz2xdy2zfpppuxoptk6nseqkuwmp4vxs7evzq2j5sqxr7upcjgg4" + }, + "app.bsky.graph.unmuteThread": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.graph.unmuteThread", + "cid": "bafyreibrx4wsi4goubxlnt7phhvnqrgmeaegxxzaf7yahnjflmtydwvaqe" + }, + "app.bsky.graph.verification": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.graph.verification", + "cid": "bafyreigtqlpdf4i3lbo3ficqhpbphawrzd7gwubbsyefkaoxuj3fvu5vcm" + }, + "app.bsky.labeler.defs": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.labeler.defs", + "cid": "bafyreifqglgo4mzx72bs266jumlopl3xppqgk5eg5u63l34tjkuy3vsfya" + }, + "app.bsky.labeler.getServices": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.labeler.getServices", + "cid": "bafyreiezmufcg75ex22ntzcxsbskb445s5bplaqxypbedvtfdlks7oz4ke" + }, + "app.bsky.labeler.service": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.labeler.service", + "cid": "bafyreiehzlg4d57n2pygqiiej6zudfl2aefiy4dntggweodi2cgx2lgol4" + }, + "app.bsky.notification.declaration": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.notification.declaration", + "cid": "bafyreihu7rdxhlazz44t4tfknnl6hahwukbccpbti7blle6mwhs5fci5su" + }, + "app.bsky.notification.defs": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.notification.defs", + "cid": "bafyreigj3h2srtgnai46quxnkal3vzpkje4xmsirrydfpopaa2azammkwq" + }, + "app.bsky.notification.getPreferences": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.notification.getPreferences", + "cid": "bafyreibkp7iavxgklburgjz4v6zs5cu722oh4lg4gdrv5yq4nakm4attre" + }, + "app.bsky.notification.getUnreadCount": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.notification.getUnreadCount", + "cid": "bafyreidxol5yjzorzb7ceakrnsahygfxtupyingqu6rij5stds4deoxwwq" + }, + "app.bsky.notification.listActivitySubscriptions": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.notification.listActivitySubscriptions", + "cid": "bafyreie7u4xgbj2iyee45g337per4jqvcf6hlejeszhxgctdtpjg5356fq" + }, + "app.bsky.notification.listNotifications": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.notification.listNotifications", + "cid": "bafyreigousmnsubjootrgwbw4ktxqw7wt6ch7x3lqdluczpbx3jnt5ig4q" + }, + "app.bsky.notification.putActivitySubscription": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.notification.putActivitySubscription", + "cid": "bafyreifsmihcvsge4vjafdnrpxzsa53zaduehlz5vnxj2zkaz376asvsii" + }, + "app.bsky.notification.putPreferences": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.notification.putPreferences", + "cid": "bafyreig4htwes3asoz3sxzi6rgph25qouohb3tvgdj7gxnmgnva45evuju" + }, + "app.bsky.notification.putPreferencesV2": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.notification.putPreferencesV2", + "cid": "bafyreigz3gf2c553gnh2jg7l6dcgnxdcanujhosphtqclhvprfboyme2ei" + }, + "app.bsky.notification.registerPush": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.notification.registerPush", + "cid": "bafyreibbbdhx6k6xtogr4zqktlsac3wnsr36wjh3t7jvkrkv3rgjaqjgum" + }, + "app.bsky.notification.unregisterPush": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.notification.unregisterPush", + "cid": "bafyreiae4to3lon2lkqumbedp5wgoxjbzxqfoarjtzk4ib4p6rqo3gbiey" + }, + "app.bsky.notification.updateSeen": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.notification.updateSeen", + "cid": "bafyreibybrqorfyquzopvdm4jyfdhtjwxaskbzcqkjdfwmukhox4dpa7ci" + }, + "app.bsky.richtext.facet": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.richtext.facet", + "cid": "bafyreidmfvmmnzqxgkwexzt73uopc4kiycmdogbedw4ijduxobwvla6sua" + }, + "app.bsky.unspecced.defs": { + "uri": "at://did:plc:placeholder00000000000000000000/com.atproto.lexicon.schema/app.bsky.unspecced.defs", + "cid": "bafyreihd4bjmbxtrkx2m4xuiaisuguenbd5d23qsbu5njo3xxib7skwfbe" + }, + "app.bsky.unspecced.getAgeAssuranceState": { + "uri": "at://did:plc:placeholder00000000000000000000/com.atproto.lexicon.schema/app.bsky.unspecced.getAgeAssuranceState", + "cid": "bafyreih4xza4elgwnr7oazzbuftplgvnbye2eleiaui7zfkrtlgmhiidfm" + }, + "app.bsky.unspecced.getConfig": { + "uri": "at://did:plc:placeholder00000000000000000000/com.atproto.lexicon.schema/app.bsky.unspecced.getConfig", + "cid": "bafyreicy6hedmitk4y73bgtt3ogfrivhqsjg67jaksgynkonte5gjuvzjq" + }, + "app.bsky.unspecced.getOnboardingSuggestedStarterPacks": { + "uri": "at://did:plc:placeholder00000000000000000000/com.atproto.lexicon.schema/app.bsky.unspecced.getOnboardingSuggestedStarterPacks", + "cid": "bafyreic5nokdcwldofzvqnxqoewjzupd6d2opfzjy72bwnn7gpgg3n3x3q" + }, + "app.bsky.unspecced.getPopularFeedGenerators": { + "uri": "at://did:plc:placeholder00000000000000000000/com.atproto.lexicon.schema/app.bsky.unspecced.getPopularFeedGenerators", + "cid": "bafyreihp3bnetgcjqeaha5k6dk2z4q5pmh3ooqilotpxvznrp3cnsrniyq" + }, + "app.bsky.unspecced.getPostThreadOtherV2": { + "uri": "at://did:plc:placeholder00000000000000000000/com.atproto.lexicon.schema/app.bsky.unspecced.getPostThreadOtherV2", + "cid": "bafyreiagvk6u73ztjaikuir647k3f7lj3u44t4mo7c3qihw3mmll2zokra" + }, + "app.bsky.unspecced.getPostThreadV2": { + "uri": "at://did:plc:placeholder00000000000000000000/com.atproto.lexicon.schema/app.bsky.unspecced.getPostThreadV2", + "cid": "bafyreiesr6gvuhu4476lxofrv4rrw5ptsisj4lqgxmxhss5o36km2h5224" + }, + "app.bsky.unspecced.getSuggestedFeeds": { + "uri": "at://did:plc:placeholder00000000000000000000/com.atproto.lexicon.schema/app.bsky.unspecced.getSuggestedFeeds", + "cid": "bafyreie4una2mjuc2ohgprqdfxotfsyxuolcmp5xktr7mcbclcs6kracce" + }, + "app.bsky.unspecced.getSuggestedFeedsSkeleton": { + "uri": "at://did:plc:placeholder00000000000000000000/com.atproto.lexicon.schema/app.bsky.unspecced.getSuggestedFeedsSkeleton", + "cid": "bafyreihqvsdre7oxhlpl7yucsmpdupwakipyzsu2gjlkbufgmklcgr5cbq" + }, + "app.bsky.unspecced.getSuggestedStarterPacks": { + "uri": "at://did:plc:placeholder00000000000000000000/com.atproto.lexicon.schema/app.bsky.unspecced.getSuggestedStarterPacks", + "cid": "bafyreih34c76u3vbjaaukyojpsrljslmnptzpnydizyfrjtedzmwosmawy" + }, + "app.bsky.unspecced.getSuggestedStarterPacksSkeleton": { + "uri": "at://did:plc:placeholder00000000000000000000/com.atproto.lexicon.schema/app.bsky.unspecced.getSuggestedStarterPacksSkeleton", + "cid": "bafyreifw62zovmzhkufp723hvubrlqzuk26o5jmx7qtafnupm2olggzoe4" + }, + "app.bsky.unspecced.getSuggestedUsers": { + "uri": "at://did:plc:placeholder00000000000000000000/com.atproto.lexicon.schema/app.bsky.unspecced.getSuggestedUsers", + "cid": "bafyreib5qavwbqignxipudnk5jzs2inlkjxosckpxakorbk3erlscfn6ba" + }, + "app.bsky.unspecced.getSuggestedUsersSkeleton": { + "uri": "at://did:plc:placeholder00000000000000000000/com.atproto.lexicon.schema/app.bsky.unspecced.getSuggestedUsersSkeleton", + "cid": "bafyreibvcocfbsxbf2s2rzuvcovkoyq6m7yz3csxrd6mdeoiwmkjqucxke" + }, + "app.bsky.unspecced.getSuggestionsSkeleton": { + "uri": "at://did:plc:placeholder00000000000000000000/com.atproto.lexicon.schema/app.bsky.unspecced.getSuggestionsSkeleton", + "cid": "bafyreiftdh7etcw5rkoruhixbjikw5p35c2v2r6rdeujol5iql6hpru254" + }, + "app.bsky.unspecced.getTaggedSuggestions": { + "uri": "at://did:plc:placeholder00000000000000000000/com.atproto.lexicon.schema/app.bsky.unspecced.getTaggedSuggestions", + "cid": "bafyreib6e3tmwibu6qo63vixnqdzlbslm423pqow2x2u3rayaxadzh2yvi" + }, + "app.bsky.unspecced.getTrendingTopics": { + "uri": "at://did:plc:placeholder00000000000000000000/com.atproto.lexicon.schema/app.bsky.unspecced.getTrendingTopics", + "cid": "bafyreibsh44yasve5t73att24aa6qqqth4ukqekkmn527w45p3nobo5d6e" + }, + "app.bsky.unspecced.getTrends": { + "uri": "at://did:plc:placeholder00000000000000000000/com.atproto.lexicon.schema/app.bsky.unspecced.getTrends", + "cid": "bafyreif5uukfgnbzsb4yaqk4e6zjb3gxei42bodsxka7t6viq6lxnox4mq" + }, + "app.bsky.unspecced.getTrendsSkeleton": { + "uri": "at://did:plc:placeholder00000000000000000000/com.atproto.lexicon.schema/app.bsky.unspecced.getTrendsSkeleton", + "cid": "bafyreierste46lq7ihipizzhowyhqsp3qnhoacsu5gbsnmnwnpi2rqjxtu" + }, + "app.bsky.unspecced.initAgeAssurance": { + "uri": "at://did:plc:placeholder00000000000000000000/com.atproto.lexicon.schema/app.bsky.unspecced.initAgeAssurance", + "cid": "bafyreicu2zecy76tjiimkb7kbottfbmi45zxn2ierhnnafl6csyjsejp7u" + }, + "app.bsky.unspecced.searchActorsSkeleton": { + "uri": "at://did:plc:placeholder00000000000000000000/com.atproto.lexicon.schema/app.bsky.unspecced.searchActorsSkeleton", + "cid": "bafyreihzvsp2ghl2uj3h6blz5oalrl4hgfaixm2ic57birq2rorpbama3a" + }, + "app.bsky.unspecced.searchPostsSkeleton": { + "uri": "at://did:plc:placeholder00000000000000000000/com.atproto.lexicon.schema/app.bsky.unspecced.searchPostsSkeleton", + "cid": "bafyreihmduatggtrh5kk7pggqhlh73pbwlbailysbbwau5tsoae5a77py4" + }, + "app.bsky.unspecced.searchStarterPacksSkeleton": { + "uri": "at://did:plc:placeholder00000000000000000000/com.atproto.lexicon.schema/app.bsky.unspecced.searchStarterPacksSkeleton", + "cid": "bafyreibkqk7fts6bxxwb4ogatm7u4ptvzrso3ccm5imysmkecigsq24lhi" + }, + "app.bsky.video.defs": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.video.defs", + "cid": "bafyreihhvskp74rqlca3hdwbo6e4frbl3xjg3e3kukoxa3vpzvqv35phu4" + }, + "app.bsky.video.getJobStatus": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.video.getJobStatus", + "cid": "bafyreifmopxtbej4m5woupzr7yhw3yqw33tq5yjjc3fapfnhvxghnxyk6y" + }, + "app.bsky.video.getUploadLimits": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.video.getUploadLimits", + "cid": "bafyreieita2jpagr3mj7xigas6yigzz4dlgebkv6k6uqwbcs3lgkm3txd4" + }, + "app.bsky.video.uploadVideo": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.video.uploadVideo", + "cid": "bafyreiclpyq7f6dzxnm6q635i5vrj5lg6eluzzpwlzusz2ke2njfmibwce" + }, + "chat.bsky.actor.declaration": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/chat.bsky.actor.declaration", + "cid": "bafyreic52ojp5pfackrtla4ohw3yyqdwyuve67us4wx2vnguj2zr4jrvna" + }, + "chat.bsky.actor.defs": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/chat.bsky.actor.defs", + "cid": "bafyreid7zn5lul6up7j7r2afxc2pvjanutzcldwrpvmedove5paminhbni" + }, + "chat.bsky.actor.deleteAccount": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/chat.bsky.actor.deleteAccount", + "cid": "bafyreibmpkmpikvghjvne3k6tlwsg7ztcegxmreo4piourmujwvlqrv7zi" + }, + "chat.bsky.actor.exportAccountData": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/chat.bsky.actor.exportAccountData", + "cid": "bafyreihmomdawttqfmxwmxne6wjjt6zxc6ajuidkg6bndgrfqqetvkmtbe" + }, + "chat.bsky.actor.getStatus": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/chat.bsky.actor.getStatus", + "cid": "bafyreihbi5vbwwstjrawe4j5gqmwyhynkcvspvxoo6srqw55s4h32y3zeq" + }, + "chat.bsky.authFullChatClient": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/chat.bsky.authFullChatClient", + "cid": "bafyreibnfw6z4hqugl6aakswxppudyjm7agxk26tpwyufvlbgskwkcprsi" + }, + "chat.bsky.convo.acceptConvo": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/chat.bsky.convo.acceptConvo", + "cid": "bafyreiaueawe2kxesmce3xrfoj44ph4vgtkwi6vep5mdfhj3sc5hxx436q" + }, + "chat.bsky.convo.addReaction": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/chat.bsky.convo.addReaction", + "cid": "bafyreihtvs3ydbdalzi6zm7bc4wboqskgbsdvrfoct6u3vq4e626fiok4i" + }, + "chat.bsky.convo.defs": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/chat.bsky.convo.defs", + "cid": "bafyreiem3j4qa7x5fxeewkkr7vneluprn7ajlf5f3jvww5wdncvjtqaqcu" + }, + "chat.bsky.convo.deleteMessageForSelf": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/chat.bsky.convo.deleteMessageForSelf", + "cid": "bafyreifr2uytolsji26krhhnbyeweloqz4hkcdlabrfv6pf6x642qq4jwu" + }, + "chat.bsky.convo.exportAccountData": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/chat.bsky.convo.exportAccountData", + "cid": "bafyreihfj5irzczzucyvft5rovam7cjh6ga7t4sxkxrlrpeeamxotqemmu" + }, + "chat.bsky.convo.getConvo": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/chat.bsky.convo.getConvo", + "cid": "bafyreih553yqo4ovwaegy5isoyxpah5d6hdly4ytqwf6vlkduymstpug6y" + }, + "chat.bsky.convo.getConvoAvailability": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/chat.bsky.convo.getConvoAvailability", + "cid": "bafyreidhqowtt46unquxdhef2r3twrvrj3r53eh2mlxlkqs2sze37pqf5u" + }, + "chat.bsky.convo.getConvoForMembers": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/chat.bsky.convo.getConvoForMembers", + "cid": "bafyreieiig5pgd4ijbqz7jq3yomtdjih2kigkivydj7vbjk2cjmtar7bvi" + }, + "chat.bsky.convo.getConvoMembers": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/chat.bsky.convo.getConvoMembers", + "cid": "bafyreicirixf323venwojrhnsg62zkiau32jzzxclfmbdlmtmcvspeil3i" + }, + "chat.bsky.convo.getLog": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/chat.bsky.convo.getLog", + "cid": "bafyreibcsehomp7maqefqn52luml4nh77fhtbbf6vpqp4fj6v66jemluue" + }, + "chat.bsky.convo.getMessages": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/chat.bsky.convo.getMessages", + "cid": "bafyreib7bcm3h6l4ftv26d3pem5obcdmvdxgwja4a2i4e4pceb2d3lgqay" + }, + "chat.bsky.convo.getUnreadCounts": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/chat.bsky.convo.getUnreadCounts", + "cid": "bafyreicx5fzsq6yk7b3jyrma2onftg64a7r5oyr4icihjo5l2rocfllddq" + }, + "chat.bsky.convo.leaveConvo": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/chat.bsky.convo.leaveConvo", + "cid": "bafyreihvv4vhpnyct2ge4tzwk3n6bjmjfnhv6e3r4hocmobbubej3qgb3a" + }, + "chat.bsky.convo.listConvoRequests": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/chat.bsky.convo.listConvoRequests", + "cid": "bafyreifvvmcmxzmo6tyuscbfisn46dm3rvdeyps4y7mvtcekbzdy3rlbia" + }, + "chat.bsky.convo.listConvos": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/chat.bsky.convo.listConvos", + "cid": "bafyreigbcqkxeqk7xlgp7gwtm3vwefw27azm6tnnomdk4bmhnyuf3xh6eu" + }, + "chat.bsky.convo.lockConvo": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/chat.bsky.convo.lockConvo", + "cid": "bafyreihzztlimgpkqav4ailgutewxyroazojfeknpgnfzdkmglhzz2p7ge" + }, + "chat.bsky.convo.muteConvo": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/chat.bsky.convo.muteConvo", + "cid": "bafyreibe57grhhsqblf666a3vwt57bpqafs5fthcuqhon45ffee27lnebe" + }, + "chat.bsky.convo.removeReaction": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/chat.bsky.convo.removeReaction", + "cid": "bafyreih75qrsxqh6tgdcy4cq2pvwqn2ca7u2fwhybneakju4n75woqmfoy" + }, + "chat.bsky.convo.sendMessage": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/chat.bsky.convo.sendMessage", + "cid": "bafyreibl4dh33ibgnze4qqru7doxmperwwvf2hw3dhnyhooie4hk4g5wce" + }, + "chat.bsky.convo.sendMessageBatch": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/chat.bsky.convo.sendMessageBatch", + "cid": "bafyreie2nianimzhfbksdgqwseeanrs7edo4xod67p6vh2auuompjdui6y" + }, + "chat.bsky.convo.unlockConvo": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/chat.bsky.convo.unlockConvo", + "cid": "bafyreiabazie4gahrplmdy35vwqt25qlhr2qwp3fay4zfmpsl4byxyt5ry" + }, + "chat.bsky.convo.unmuteConvo": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/chat.bsky.convo.unmuteConvo", + "cid": "bafyreid4rnm3m54lygug4bv6bhbloup4yotfxkfdn4ntdvtpff4puxjdlu" + }, + "chat.bsky.convo.updateAllRead": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/chat.bsky.convo.updateAllRead", + "cid": "bafyreigmzoah6iwrkoolhr3xeswx4n7juml3e3zcnaxjbek3b62bo5malq" + }, + "chat.bsky.convo.updateRead": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/chat.bsky.convo.updateRead", + "cid": "bafyreigc6wuvsiztbbzvbmx5zsyysaxpttisxz4cdx5btaz24garqocisi" + }, + "chat.bsky.embed.joinLink": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/chat.bsky.embed.joinLink", + "cid": "bafyreihxplna4a6vohcrvgvf5bojpbgeipwahetbvpdlu6v2rhqt26rez4" + }, + "chat.bsky.group.addMembers": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/chat.bsky.group.addMembers", + "cid": "bafyreicda57byqfefotgp5boczfcayhmlvv2kangkhvkdzx7fmm3ul7iuu" + }, + "chat.bsky.group.approveJoinRequest": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/chat.bsky.group.approveJoinRequest", + "cid": "bafyreienhjyklyhrhq7bn4mqbgdyisjmrlj5frypwmb2ljuiabdsmcfcya" + }, + "chat.bsky.group.createGroup": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/chat.bsky.group.createGroup", + "cid": "bafyreicg7bhotxsli6de6px6h4jfnzfldn562ptaaxyjufybyam536emrq" + }, + "chat.bsky.group.createJoinLink": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/chat.bsky.group.createJoinLink", + "cid": "bafyreiemk65txz7vyfpojfxaxwkuteh3idudptz66xi5bohjhrtms6d4ui" + }, + "chat.bsky.group.defs": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/chat.bsky.group.defs", + "cid": "bafyreihdf6nyjipv3dbafupbwl7rntdjmhrdgzukq3rbq5xijy2tqrbfiy" + }, + "chat.bsky.group.disableJoinLink": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/chat.bsky.group.disableJoinLink", + "cid": "bafyreiajuolsuoue54zefbf2jk7liezw5xgl7ii2bedtzdmke37kooi7ki" + }, + "chat.bsky.group.editGroup": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/chat.bsky.group.editGroup", + "cid": "bafyreid6rfifgbeptlyjhaut7vc33myzjl77csupzaki2q3sgu5a4l5lom" + }, + "chat.bsky.group.editJoinLink": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/chat.bsky.group.editJoinLink", + "cid": "bafyreialgoa5agpq7xbapaetq3pztaprxpn3yhsyng2agwpfekwxvr5btm" + }, + "chat.bsky.group.enableJoinLink": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/chat.bsky.group.enableJoinLink", + "cid": "bafyreiawchlxflo5gygw64gumpsqa3dhzcobyb4u3hurubxfcds52nvohm" + }, + "chat.bsky.group.getJoinLinkPreviews": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/chat.bsky.group.getJoinLinkPreviews", + "cid": "bafyreicj56hhgnvrpr25mo3jbxsioyfuatj5e2bs57atenqizvmzlygxhu" + }, + "chat.bsky.group.listJoinRequests": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/chat.bsky.group.listJoinRequests", + "cid": "bafyreiacxeghdbyiyeantijbtywxua3yq7eve2iqdojrnk2p64dpe42n3e" + }, + "chat.bsky.group.listMutualGroups": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/chat.bsky.group.listMutualGroups", + "cid": "bafyreicw6bkqdnlu2cvusnhwfdf2hofb4yf5qhza3k6h7qmxgwa3kqmwuy" + }, + "chat.bsky.group.rejectJoinRequest": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/chat.bsky.group.rejectJoinRequest", + "cid": "bafyreicig4onygi2qjnpgyiekm3c6kq4ia56s5ulwlistjao6x6sp647te" + }, + "chat.bsky.group.removeMembers": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/chat.bsky.group.removeMembers", + "cid": "bafyreigdvm7xq2pxlwp5wu4bp3u7edmbm6p2qsnnit4srl2e4iychofo5m" + }, + "chat.bsky.group.requestJoin": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/chat.bsky.group.requestJoin", + "cid": "bafyreihrekak34m4uwgqednndxm7djn7i73dscawc55kjj6lnextycdbxe" + }, + "chat.bsky.group.updateJoinRequestsRead": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/chat.bsky.group.updateJoinRequestsRead", + "cid": "bafyreibsq44qulpbaxzpq2ujy57y3qznte2y2c4qi7oiyfeofp4cmrcqgm" + }, + "chat.bsky.group.withdrawJoinRequest": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/chat.bsky.group.withdrawJoinRequest", + "cid": "bafyreiex7zdds4yhfxxvvctcu7zgov6ilje5ju7qk7v2b7p2ynp3m7tqyu" + }, + "chat.bsky.moderation.defs": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/chat.bsky.moderation.defs", + "cid": "bafyreiaj3q2uglbjyauepqigz3hdgs4np5xmwdouf6ylwdwmqvbirnpxye" + }, + "chat.bsky.moderation.getActorMetadata": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/chat.bsky.moderation.getActorMetadata", + "cid": "bafyreianlybfxw3tkuxl4c2c3nnirerataarfz3sfdutkatz2w3jsxm54a" + }, + "chat.bsky.moderation.getConvo": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/chat.bsky.moderation.getConvo", + "cid": "bafyreichtqgu2d3uafvhvaihnxmtilmqdll5wgebbztt4vakuwdnicgevq" + }, + "chat.bsky.moderation.getConvoMembers": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/chat.bsky.moderation.getConvoMembers", + "cid": "bafyreifqk2gdgufo2iso5l7d7io6bpgtnkgke4dxdpkx6ecq4uuhuh2b2a" + }, + "chat.bsky.moderation.getConvos": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/chat.bsky.moderation.getConvos", + "cid": "bafyreigix74hirmx46zroagwuo3asdamklk6h22bzfth3abxcch57xyos4" + }, + "chat.bsky.moderation.getMessageContext": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/chat.bsky.moderation.getMessageContext", + "cid": "bafyreifthdkf3l5ovz7n5hgtq4oihw6iay5moluzriwmxmcx2ew2ss4l6i" + }, + "chat.bsky.moderation.subscribeModEvents": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/chat.bsky.moderation.subscribeModEvents", + "cid": "bafyreif2vevked4t7d26hslkygtfk3cq2vgu2p2z6ubwzckasu4ufpqf5e" + }, + "chat.bsky.moderation.updateActorAccess": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/chat.bsky.moderation.updateActorAccess", + "cid": "bafyreihnuaaezmq5rbrsdcduxrpxxhm6crcyrxzu5vhfxjuobntaqabt2i" + }, + "chat.bsky.notification.defs": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/chat.bsky.notification.defs", + "cid": "bafyreiewjard4dzc44kh3v3w477oepm6gbbjfjsy7vlm5kwxvf73m7qh6u" + }, + "chat.bsky.notification.getPreferences": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/chat.bsky.notification.getPreferences", + "cid": "bafyreifj5m552wgmczmbmo7arqhg7fq4x5cjhygca7bnewzqicsega2xni" + }, + "chat.bsky.notification.putPreferences": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/chat.bsky.notification.putPreferences", + "cid": "bafyreihsydb3ttbb7zudwpgcs4qws3fga6ykauc26d4ozezi5xvgakosoq" + }, + "com.atproto.admin.defs": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.admin.defs", + "cid": "bafyreiak73emfcmcmityemkvldgbbvi3dgxszlg6qvm6r73s2qofu3rkc4" + }, + "com.atproto.admin.deleteAccount": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.admin.deleteAccount", + "cid": "bafyreiawxiwem24matzkumytylozh2fk7lfnwddmjuzo5p7g5ph3unduru" + }, + "com.atproto.admin.disableAccountInvites": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.admin.disableAccountInvites", + "cid": "bafyreiay3q67wp4cco6fvri23lbvwkn2ew52jc6ia3umco6hdotekxool4" + }, + "com.atproto.admin.disableInviteCodes": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.admin.disableInviteCodes", + "cid": "bafyreids2ptu2s36mtscnmgsaf3ocqsbrb63dbghryec7qigx3xly5wp2q" + }, + "com.atproto.admin.enableAccountInvites": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.admin.enableAccountInvites", + "cid": "bafyreihnbw4g4ba6xhxu64vdqee5xoacosurucuootksduysjpyestox5i" + }, + "com.atproto.admin.getAccountInfo": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.admin.getAccountInfo", + "cid": "bafyreidfwekzlh2kvvctg2xt2iye3z5cohe332fadncvvbwuurt4dr4mhu" + }, + "com.atproto.admin.getAccountInfos": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.admin.getAccountInfos", + "cid": "bafyreicnusy7d4o6kebwhhvx7axe44i3pbnuobgcfpxpory77rfbyigkbm" + }, + "com.atproto.admin.getInviteCodes": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.admin.getInviteCodes", + "cid": "bafyreibpbpoimdliveavl5qhbfgmytwrm3ook3ltspsbducu7q3qkqspmy" + }, + "com.atproto.admin.getSubjectStatus": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.admin.getSubjectStatus", + "cid": "bafyreib66oa3k2emaxlfpg6zofoyvclxulbdjpgfnd3ojsy7wzwrpefno4" + }, + "com.atproto.admin.searchAccounts": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.admin.searchAccounts", + "cid": "bafyreiagu7zctkpwgwm42cmtk4tigsin3sqiwfqfjl6fol5fq3wln4ufbu" + }, + "com.atproto.admin.sendEmail": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.admin.sendEmail", + "cid": "bafyreid5g5kwe4pvswnf3wkzyhwyk2xez523qhngcerfjxvmdl5ajmjxja" + }, + "com.atproto.admin.updateAccountEmail": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.admin.updateAccountEmail", + "cid": "bafyreidroywyplsfcvr6pw7otcgykeyjiefnay3pjbr56bnmsoqlog4qda" + }, + "com.atproto.admin.updateAccountHandle": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.admin.updateAccountHandle", + "cid": "bafyreiefitr6xj2xaxdskmxceyfchjh25x52cm6j7fm7jb7heqmtgitvoq" + }, + "com.atproto.admin.updateAccountPassword": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.admin.updateAccountPassword", + "cid": "bafyreihxzrpoonhqlmeqsvnw3hsdnzlr3kwfpgzxxll7bchemecakq3uwu" + }, + "com.atproto.admin.updateAccountSigningKey": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.admin.updateAccountSigningKey", + "cid": "bafyreifkuqbdhse6dmc4gnxwt67eyyezsni7kor2vhdycnq6vjlbrkwdda" + }, + "com.atproto.admin.updateSubjectStatus": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.admin.updateSubjectStatus", + "cid": "bafyreihehtzhfy5tyopelgmlx3s66f6vmoiqf7inqkv6t5fmmre7asbv74" + }, + "com.atproto.identity.defs": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.identity.defs", + "cid": "bafyreibn5s5nmctdghjtq5klp5onggvrrjibm6qkklhaqg3iu2mhwr6ypq" + }, + "com.atproto.identity.getRecommendedDidCredentials": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.identity.getRecommendedDidCredentials", + "cid": "bafyreiclshqo2uxjgzkiwjbhx4pwlg7su3otfbk4glirpxmcedfjiutchm" + }, + "com.atproto.identity.refreshIdentity": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.identity.refreshIdentity", + "cid": "bafyreiemujdf3yaqu3ogqdtcvqa2ciqy4lgfy5kv6nlseqsr7mbypufsli" + }, + "com.atproto.identity.requestPlcOperationSignature": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.identity.requestPlcOperationSignature", + "cid": "bafyreidg35oe7jdrb7q6g6zrh43u27xtttz4mzfofhfyngysxpvl5oouwi" + }, + "com.atproto.identity.resolveDid": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.identity.resolveDid", + "cid": "bafyreieuxzze4jnd3sxksxr2zd6uzllbfwsd734fvvdmb6f3cy6jwypcxu" + }, + "com.atproto.identity.resolveHandle": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.identity.resolveHandle", + "cid": "bafyreihmqiz5zcvbed5ydtu7souaqkmtphzjnzrii6qesczxpixzhy52gu" + }, + "com.atproto.identity.resolveIdentity": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.identity.resolveIdentity", + "cid": "bafyreihz7wvwklgclxen34fmmqdguxvx4pwhwp2u4jmasotpybrrcvocdm" + }, + "com.atproto.identity.signPlcOperation": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.identity.signPlcOperation", + "cid": "bafyreidss56f7mx6wf6dqi5zsei5ul36rt6tx4miionzrqodh33wcrefeu" + }, + "com.atproto.identity.submitPlcOperation": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.identity.submitPlcOperation", + "cid": "bafyreighyaq4f65yjl464nhasj7f5ibf5mpkfuxhr6nmn6skfuffvpv6vi" + }, + "com.atproto.identity.updateHandle": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.identity.updateHandle", + "cid": "bafyreids3w5wqxqsklwn34m73jwokj2gc3lzv2um5ngfz2e7a5vnsz7joq" + }, + "com.atproto.label.defs": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.label.defs", + "cid": "bafyreianoilzgo2njqfwuuwcv3trfsvc452wtmmfo4jgfq7ypkkysi2kdi" + }, + "com.atproto.label.queryLabels": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.label.queryLabels", + "cid": "bafyreiefwfo6dn5tsp5mstgvhcmdwweroa3bfhavr4ekbwm6rikcglsqve" + }, + "com.atproto.label.subscribeLabels": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.label.subscribeLabels", + "cid": "bafyreie6hmxroxlelbrzpji7sajpsq3adtbd4m6ipeieghavuyjlbrt5oa" + }, + "com.atproto.lexicon.resolveLexicon": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.lexicon.resolveLexicon", + "cid": "bafyreie2nqd4ugtxizruqvoj2nifz6yjdeigkx3cym55geqsx3xhlf6sli" + }, + "com.atproto.lexicon.schema": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.lexicon.schema", + "cid": "bafyreibddpomwj65bmz3hl4he7payr46sditxqmuc3zw43cnev2s7wwa3i" + }, + "com.atproto.moderation.createReport": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.moderation.createReport", + "cid": "bafyreigli77c67ucvy4zsgcbt3vsocrdxqf62pbwoxdb6jq5ygfjcvxbim" + }, + "com.atproto.moderation.defs": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.moderation.defs", + "cid": "bafyreibecurmetfii4q7oa7ki5qi2uuaimjqe6phdlxmy3rlypsvvolstm" + }, + "com.atproto.repo.applyWrites": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.repo.applyWrites", + "cid": "bafyreigserrq6z46d7vgnxf3m2c4sgld2itq7eyapwfoc7gudfjry3h5ca" + }, + "com.atproto.repo.createRecord": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.repo.createRecord", + "cid": "bafyreian2jwdclnou5pwhoy23sous7qzkj5jqzdsnhso7aou26nwt5ziw4" + }, + "com.atproto.repo.defs": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.repo.defs", + "cid": "bafyreig6nmxec7j7ph2zx7shaljsugmndy7garsoi7td3x5bird6gllbpa" + }, + "com.atproto.repo.deleteRecord": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.repo.deleteRecord", + "cid": "bafyreigptpsppdmu6z2todwq6jbdslnx2s37rghzhieagfgtkhgw77ykh4" + }, + "com.atproto.repo.describeRepo": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.repo.describeRepo", + "cid": "bafyreiadrjarwkytntdjfcpjlsrju6avmrvlaqo24u67hdtpaxcj3uoro4" + }, + "com.atproto.repo.getRecord": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.repo.getRecord", + "cid": "bafyreiho5nshry2twf7p2emfsxyx22vjidufpef65c7khunteasgdxf37u" + }, + "com.atproto.repo.importRepo": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.repo.importRepo", + "cid": "bafyreiaadqoawzgzxwmylpo3gm3qy5dvfyssjngk4kmc6xkb5h3wzkmvh4" + }, + "com.atproto.repo.listMissingBlobs": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.repo.listMissingBlobs", + "cid": "bafyreihsb6zx2p7ujy6azcs5l5dvdsiad3d7zgft22vcfcqhpblxifvxje" + }, + "com.atproto.repo.listRecords": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.repo.listRecords", + "cid": "bafyreiex5tdyevi7e4emkgnnngb36koqegu5zqxssnoq5xa4pln22nldau" + }, + "com.atproto.repo.putRecord": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.repo.putRecord", + "cid": "bafyreiarzlpc43cmf5zccaomgk5eaujipkgaxnlpyyhg4twbt3zrlzvv64" + }, + "com.atproto.repo.strongRef": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.repo.strongRef", + "cid": "bafyreifbx7dk2lqddlzbar7n5sihedkz5b5ganyrbpcme7yyah65iv62ce" + }, + "com.atproto.repo.uploadBlob": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.repo.uploadBlob", + "cid": "bafyreiewhhnp2wiprruttkzd7fu52c5wxzkjislb3trn7whhn33aplxdoi" + }, + "com.atproto.server.activateAccount": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.server.activateAccount", + "cid": "bafyreigupkzx2bqbqstfh2okozujhmn34komj4t4dea4j3ty236ilmwgce" + }, + "com.atproto.server.checkAccountStatus": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.server.checkAccountStatus", + "cid": "bafyreihwm2ll4dzeqaih4uuzxqizumwqhh2ap4ahhtvj3e7q52cowul7ty" + }, + "com.atproto.server.confirmEmail": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.server.confirmEmail", + "cid": "bafyreidgbfqpuefnlqjw252erprbuandysef3732kbp5g2porrjaaex5rq" + }, + "com.atproto.server.createAccount": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.server.createAccount", + "cid": "bafyreidvhpgnjvbrqu4caqlgzfkieo4ksn4kjksxxvlz4iv3wprlkdaw4e" + }, + "com.atproto.server.createAppPassword": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.server.createAppPassword", + "cid": "bafyreicgol6zukganl4pknoh6sqwlhhlenbxibmn4pskg3roa5xu2j3ol4" + }, + "com.atproto.server.createInviteCode": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.server.createInviteCode", + "cid": "bafyreib4crdxdb3ymqdm5eggwgipb5t7tguxnufplpeav7pe43c5trl2ce" + }, + "com.atproto.server.createInviteCodes": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.server.createInviteCodes", + "cid": "bafyreibbwaydg7lozghm6iiw7tmuy2ko4uqcyyji4nnpp4v6yylae65o7e" + }, + "com.atproto.server.createSession": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.server.createSession", + "cid": "bafyreig3p3umilvktnf5cdlzcfcs46pj5qcqb5tg5vqftlskxmqszhop2i" + }, + "com.atproto.server.deactivateAccount": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.server.deactivateAccount", + "cid": "bafyreie3efb57y3cfncmsvp3u6medeimergdqndjbbnm6dhugcdgxdn67a" + }, + "com.atproto.server.defs": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.server.defs", + "cid": "bafyreid5wvwnmztjivuvu7j5a6hzch26kdtsx5qs4yup7e2qjoddpwcs4y" + }, + "com.atproto.server.deleteAccount": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.server.deleteAccount", + "cid": "bafyreig6mjzc5l6doh6qasyps2hrw3lk56neoajjzvznnh7yfwdsek7ngy" + }, + "com.atproto.server.deleteSession": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.server.deleteSession", + "cid": "bafyreihf7louq2vhkmswy6qeyrixk2fr52olshivc4mtjkm7v447oljfue" + }, + "com.atproto.server.describeServer": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.server.describeServer", + "cid": "bafyreidrqwnv3bytwtiupdlfftdtjfjldrmjjne7sftrdplnmbzvojmjgu" + }, + "com.atproto.server.getAccountInviteCodes": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.server.getAccountInviteCodes", + "cid": "bafyreiasyd3ric6b4jb4u4v2khzmudhbds3qoo7ycluhglwu4qssfk4lte" + }, + "com.atproto.server.getServiceAuth": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.server.getServiceAuth", + "cid": "bafyreig62bx32vrjvsllzrdmz53dgeck3ngjr2536u7jpp3wuh5zyulovy" + }, + "com.atproto.server.getSession": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.server.getSession", + "cid": "bafyreiemqus6i7fomp2pkzqm5772hr52x354ni6sqrumigqga57kgicy2y" + }, + "com.atproto.server.listAppPasswords": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.server.listAppPasswords", + "cid": "bafyreieytcf6v6bpxjdv34e3562j4c2dme2x36ucltj25n3sbnqsp7gzha" + }, + "com.atproto.server.refreshSession": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.server.refreshSession", + "cid": "bafyreidba6hc2j7iqdon24oq7xjfdko6qru3yxdgtkhrul5a5ntf5cg2fy" + }, + "com.atproto.server.requestAccountDelete": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.server.requestAccountDelete", + "cid": "bafyreieirevzlc6hq43bplyw5o6posak5hmx3z2yzlchqu5rva7v7ctmvy" + }, + "com.atproto.server.requestEmailConfirmation": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.server.requestEmailConfirmation", + "cid": "bafyreidkek3zwuwhyvs7ct4stvtjtsm3lwjj5q4c3tuf25x5e2d5w3xlx4" + }, + "com.atproto.server.requestEmailUpdate": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.server.requestEmailUpdate", + "cid": "bafyreifilj2jdzucss56mnu7ynoeeebovgm6qfnwfvy6a26atdbaft2lvq" + }, + "com.atproto.server.requestPasswordReset": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.server.requestPasswordReset", + "cid": "bafyreibs4jk6ndisvztiqprofgm24rluzkotwqbzbqn6i26upcaxa4xr2y" + }, + "com.atproto.server.reserveSigningKey": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.server.reserveSigningKey", + "cid": "bafyreiamtsl3vm5js4f5verpzj7hd7v67e2zulrkc4nacalwzhq6mg7pae" + }, + "com.atproto.server.resetPassword": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.server.resetPassword", + "cid": "bafyreicewdg6wmgbvgt4slwmnfneuca3fuqtyqbv4c7ga3xmuukooergmq" + }, + "com.atproto.server.revokeAppPassword": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.server.revokeAppPassword", + "cid": "bafyreifj4735dx72os6ro24btfqfofmi3p2di6p3efj2erzueksjzf4mnm" + }, + "com.atproto.server.updateEmail": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.server.updateEmail", + "cid": "bafyreigzkpb72i2xqwfxhhmq6ri7reomep4h67it7r3vwlgdswdqg5aqau" + }, + "com.atproto.sync.defs": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.sync.defs", + "cid": "bafyreifreb3qxk3k7wtvivo5742zoy3h5556umyaox3usei5qjivapimqa" + }, + "com.atproto.sync.getBlob": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.sync.getBlob", + "cid": "bafyreifdvysv4cqey5zcsc6kwvzseu6lrazbkhw2nk7zojkjryqcbxjcp4" + }, + "com.atproto.sync.getBlocks": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.sync.getBlocks", + "cid": "bafyreih4kc3tm4z5z3pajhs53xr27ysajifu3yhz2ql5naqef6a2qphafm" + }, + "com.atproto.sync.getCheckout": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.sync.getCheckout", + "cid": "bafyreie5ryt55y5bmisyv5sd75g5rmr3rwbeg5lhlcmlchh3wxi6zghi2q" + }, + "com.atproto.sync.getHead": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.sync.getHead", + "cid": "bafyreicsy6c4ds7bei6eswqzdguke5gvenb7iaoxubzstt75xzpjaibqdq" + }, + "com.atproto.sync.getHostStatus": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.sync.getHostStatus", + "cid": "bafyreif6qtt2mlvsfobbib3zbrb6pzovmeer7jqadfuewd32u2fag4f3xy" + }, + "com.atproto.sync.getLatestCommit": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.sync.getLatestCommit", + "cid": "bafyreihapl53y44hsrfyqbxtv7ifodph2hmqhsylhd2q3alwl3awo5655i" + }, + "com.atproto.sync.getRecord": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.sync.getRecord", + "cid": "bafyreiaqangr7wierobeonshlwcg6c2n7q6ighuudrrtvjedh5hfwj4oi4" + }, + "com.atproto.sync.getRepo": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.sync.getRepo", + "cid": "bafyreiasybkrbueat6mhm7syxspm3wdqs4mbed2vq47yt4awafdobnb2g4" + }, + "com.atproto.sync.getRepoStatus": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.sync.getRepoStatus", + "cid": "bafyreicqktondarcqoftzl6kleji2w5q6qwirfbxa3elsg4lzqeedkjg3q" + }, + "com.atproto.sync.listBlobs": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.sync.listBlobs", + "cid": "bafyreihqhkdaa5jx33466fjdbwzhylsv7qsxqzz4somnpbhcw5mt3777du" + }, + "com.atproto.sync.listHosts": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.sync.listHosts", + "cid": "bafyreiczdfusldizhqfqmmuznb2gu7m6uaidtipctj7fxvevdoesaezu5m" + }, + "com.atproto.sync.listRepos": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.sync.listRepos", + "cid": "bafyreiarzlu4gul274w5klq3ws643onjohcv4n4xtsatmshso34ee3njai" + }, + "com.atproto.sync.listReposByCollection": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.sync.listReposByCollection", + "cid": "bafyreierjdx6tuy5igybyz6drap6zlhvzrm36wnea5fvklrknygs6gk6my" + }, + "com.atproto.sync.notifyOfUpdate": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.sync.notifyOfUpdate", + "cid": "bafyreidyifkxvioxdgrvaa74rhuiywtotq4ofajceuhhf6g7ppvrm2kjku" + }, + "com.atproto.sync.requestCrawl": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.sync.requestCrawl", + "cid": "bafyreigwb4juy2ypv2xfx2p2pklqpv6andjrgh2pdgivjxddvymfzehxzu" + }, + "com.atproto.sync.subscribeRepos": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.sync.subscribeRepos", + "cid": "bafyreic6fm5atifiaq67u44dtxc3ufjbq3z7yysryjrzrw37hkb32yajbi" + }, + "com.germnetwork.declaration": { + "uri": "at://did:plc:qyqmmncrm6qx33kpy7vqndik/com.atproto.lexicon.schema/com.germnetwork.declaration", + "cid": "bafyreiekwjmxshje655olra4mata7npso7bbgytc4fop77ycjtrbewwi3y" + }, + "tools.ozone.moderation.defs": { + "uri": "at://did:plc:placeholder00000000000000000000/com.atproto.lexicon.schema/tools.ozone.moderation.defs", + "cid": "bafyreihfuu5u5uiub2xvzt56re4pxor2mx7aoukt5kkvv65rfdvazyvn5e" + }, + "tools.ozone.queue.defs": { + "uri": "at://did:plc:placeholder00000000000000000000/com.atproto.lexicon.schema/tools.ozone.queue.defs", + "cid": "bafyreibj5bcm4vh4oypkzfblbbswnrr5zcyy5fakiqcp4shs4s3tffgt3e" + }, + "tools.ozone.report.defs": { + "uri": "at://did:plc:placeholder00000000000000000000/com.atproto.lexicon.schema/tools.ozone.report.defs", + "cid": "bafyreib62x76t7vneupmsd3ahtnylyyc4345rhmp3gvdsmaxfcf5xgv624" + }, + "tools.ozone.team.defs": { + "uri": "at://did:plc:placeholder00000000000000000000/com.atproto.lexicon.schema/tools.ozone.team.defs", + "cid": "bafyreifj3hxfarkbpbcnjbckaljyyrwmrbaz3sy4ttx5pbzrdv7ea2pmby" + } + } +} \ No newline at end of file diff --git a/lexicons/app/bsky/actor/defs.json b/lexicons/app/bsky/actor/defs.json new file mode 100644 index 0000000000..115aad02b8 --- /dev/null +++ b/lexicons/app/bsky/actor/defs.json @@ -0,0 +1,868 @@ +{ + "lexicon": 1, + "id": "app.bsky.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 + }, + "pronouns": { + "type": "string" + }, + "avatar": { + "type": "string", + "format": "uri" + }, + "associated": { + "type": "ref", + "ref": "#profileAssociated" + }, + "viewer": { + "type": "ref", + "ref": "#viewerState" + }, + "labels": { + "type": "array", + "items": { + "type": "ref", + "ref": "com.atproto.label.defs#label" + } + }, + "createdAt": { + "type": "string", + "format": "datetime" + }, + "verification": { + "type": "ref", + "ref": "#verificationState" + }, + "status": { + "type": "ref", + "ref": "#statusView" + }, + "debug": { + "type": "unknown", + "description": "Debug information for internal development" + } + } + }, + "profileView": { + "type": "object", + "required": ["did", "handle"], + "properties": { + "did": { + "type": "string", + "format": "did" + }, + "handle": { + "type": "string", + "format": "handle" + }, + "displayName": { + "type": "string", + "maxGraphemes": 64, + "maxLength": 640 + }, + "pronouns": { + "type": "string" + }, + "description": { + "type": "string", + "maxGraphemes": 256, + "maxLength": 2560 + }, + "avatar": { + "type": "string", + "format": "uri" + }, + "associated": { + "type": "ref", + "ref": "#profileAssociated" + }, + "indexedAt": { + "type": "string", + "format": "datetime" + }, + "createdAt": { + "type": "string", + "format": "datetime" + }, + "viewer": { + "type": "ref", + "ref": "#viewerState" + }, + "labels": { + "type": "array", + "items": { + "type": "ref", + "ref": "com.atproto.label.defs#label" + } + }, + "verification": { + "type": "ref", + "ref": "#verificationState" + }, + "status": { + "type": "ref", + "ref": "#statusView" + }, + "debug": { + "type": "unknown", + "description": "Debug information for internal development" + } + } + }, + "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 + }, + "pronouns": { + "type": "string" + }, + "website": { + "type": "string", + "format": "uri" + }, + "avatar": { + "type": "string", + "format": "uri" + }, + "banner": { + "type": "string", + "format": "uri" + }, + "followersCount": { + "type": "integer" + }, + "followsCount": { + "type": "integer" + }, + "postsCount": { + "type": "integer" + }, + "associated": { + "type": "ref", + "ref": "#profileAssociated" + }, + "joinedViaStarterPack": { + "type": "ref", + "ref": "app.bsky.graph.defs#starterPackViewBasic" + }, + "indexedAt": { + "type": "string", + "format": "datetime" + }, + "createdAt": { + "type": "string", + "format": "datetime" + }, + "viewer": { + "type": "ref", + "ref": "#viewerState" + }, + "labels": { + "type": "array", + "items": { + "type": "ref", + "ref": "com.atproto.label.defs#label" + } + }, + "pinnedPost": { + "type": "ref", + "ref": "com.atproto.repo.strongRef" + }, + "verification": { + "type": "ref", + "ref": "#verificationState" + }, + "status": { + "type": "ref", + "ref": "#statusView" + }, + "debug": { + "type": "unknown", + "description": "Debug information for internal development" + } + } + }, + "profileAssociated": { + "type": "object", + "properties": { + "lists": { + "type": "integer" + }, + "feedgens": { + "type": "integer" + }, + "starterPacks": { + "type": "integer" + }, + "labeler": { + "type": "boolean" + }, + "chat": { + "type": "ref", + "ref": "#profileAssociatedChat" + }, + "activitySubscription": { + "type": "ref", + "ref": "#profileAssociatedActivitySubscription" + }, + "germ": { + "type": "ref", + "ref": "#profileAssociatedGerm" + } + } + }, + "profileAssociatedChat": { + "type": "object", + "required": ["allowIncoming"], + "properties": { + "allowIncoming": { + "type": "string", + "knownValues": ["all", "none", "following"] + }, + "allowGroupInvites": { + "type": "string", + "knownValues": ["all", "none", "following"] + } + } + }, + "profileAssociatedGerm": { + "type": "object", + "required": ["showButtonTo", "messageMeUrl"], + "properties": { + "messageMeUrl": { + "type": "string", + "format": "uri" + }, + "showButtonTo": { + "type": "string", + "knownValues": ["usersIFollow", "everyone"] + } + } + }, + "profileAssociatedActivitySubscription": { + "type": "object", + "required": ["allowSubscriptions"], + "properties": { + "allowSubscriptions": { + "type": "string", + "knownValues": ["followers", "mutuals", "none"] + } + } + }, + "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": "app.bsky.graph.defs#listViewBasic" + }, + "blockedBy": { + "type": "boolean" + }, + "blocking": { + "type": "string", + "format": "at-uri" + }, + "blockingByList": { + "type": "ref", + "ref": "app.bsky.graph.defs#listViewBasic" + }, + "following": { + "type": "string", + "format": "at-uri" + }, + "followedBy": { + "type": "string", + "format": "at-uri" + }, + "knownFollowers": { + "description": "This property is present only in selected cases, as an optimization.", + "type": "ref", + "ref": "#knownFollowers" + }, + "activitySubscription": { + "description": "This property is present only in selected cases, as an optimization.", + "type": "ref", + "ref": "app.bsky.notification.defs#activitySubscription" + } + } + }, + "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": "#profileViewBasic" + } + } + } + }, + "verificationState": { + "type": "object", + "description": "Represents the verification information about the user this object is attached to.", + "required": ["verifications", "verifiedStatus", "trustedVerifierStatus"], + "properties": { + "verifications": { + "type": "array", + "description": "All verifications issued by trusted verifiers on behalf of this user. Verifications by untrusted verifiers are not included.", + "items": { + "type": "ref", + "ref": "#verificationView" + } + }, + "verifiedStatus": { + "type": "string", + "description": "The user's status as a verified account.", + "knownValues": ["valid", "invalid", "none"] + }, + "trustedVerifierStatus": { + "type": "string", + "description": "The user's status as a trusted verifier.", + "knownValues": ["valid", "invalid", "none"] + } + } + }, + "verificationView": { + "type": "object", + "description": "An individual verification for an associated subject.", + "required": ["issuer", "uri", "isValid", "createdAt"], + "properties": { + "issuer": { + "type": "string", + "description": "The user who issued this verification.", + "format": "did" + }, + "issuerDisplayName": { + "type": "string", + "description": "The display name of the issuer." + }, + "issuerHandle": { + "type": "string", + "description": "The handle of the issuer.", + "format": "handle" + }, + "uri": { + "type": "string", + "description": "The AT-URI of the verification record.", + "format": "at-uri" + }, + "isValid": { + "type": "boolean", + "description": "True if the verification passes validation, otherwise false." + }, + "createdAt": { + "type": "string", + "description": "Timestamp when the verification was created.", + "format": "datetime" + } + } + }, + "preferences": { + "type": "array", + "items": { + "type": "union", + "refs": [ + "#adultContentPref", + "#contentLabelPref", + "#savedFeedsPref", + "#savedFeedsPrefV2", + "#personalDetailsPref", + "#declaredAgePref", + "#feedViewPref", + "#threadViewPref", + "#interestsPref", + "#mutedWordsPref", + "#hiddenPostsPref", + "#bskyAppStatePref", + "#labelersPref", + "#postInteractionSettingsPref", + "#verificationPrefs", + "#liveEventPreferences" + ] + } + }, + "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": "app.bsky.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." + } + } + }, + "declaredAgePref": { + "type": "object", + "description": "Read-only preference containing value(s) inferred from the user's declared birthdate. Absence of this preference object in the response indicates that the user has not made a declaration.", + "properties": { + "isOverAge13": { + "type": "boolean", + "description": "Indicates if the user has declared that they are over 13 years of age." + }, + "isOverAge16": { + "type": "boolean", + "description": "Indicates if the user has declared that they are over 16 years of age." + }, + "isOverAge18": { + "type": "boolean", + "description": "Indicates if the user has declared that they are over 18 years of age." + } + } + }, + "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." + }, + "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", "random", "hotness"] + } + } + }, + "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": "app.bsky.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": "app.bsky.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": "#labelerPrefItem" + } + } + } + }, + "labelerPrefItem": { + "type": "object", + "required": ["did"], + "properties": { + "did": { + "type": "string", + "format": "did" + } + } + }, + "bskyAppStatePref": { + "description": "A grab bag of state that's specific to the bsky.app program. Third-party apps shouldn't use this.", + "type": "object", + "properties": { + "activeProgressGuide": { + "type": "ref", + "ref": "#bskyAppProgressGuide" + }, + "isBetaUser": { + "description": "Indicates if the user is participating in the beta features program.", + "type": "boolean" + }, + "queuedNudges": { + "description": "An array of tokens which identify nudges (modals, popups, tours, highlight dots) that should be shown to the user.", + "type": "array", + "maxLength": 1000, + "items": { + "type": "string", + "maxLength": 100 + } + }, + "nuxs": { + "description": "Storage for NUXs the user has encountered.", + "type": "array", + "maxLength": 100, + "items": { + "type": "ref", + "ref": "app.bsky.actor.defs#nux" + } + } + } + }, + "bskyAppProgressGuide": { + "description": "If set, an active progress guide. Once completed, can be set to undefined. Should have unspecced fields tracking progress.", + "type": "object", + "required": ["guide"], + "properties": { + "guide": { + "type": "string", + "maxLength": 100 + } + } + }, + "nux": { + "type": "object", + "description": "A new user experiences (NUX) storage object", + "required": ["id", "completed"], + "properties": { + "id": { + "type": "string", + "maxLength": 100 + }, + "completed": { + "type": "boolean", + "default": false + }, + "data": { + "description": "Arbitrary data for the NUX. The structure is defined by the NUX itself. Limited to 300 characters.", + "type": "string", + "maxLength": 3000, + "maxGraphemes": 300 + }, + "expiresAt": { + "type": "string", + "format": "datetime", + "description": "The date and time at which the NUX will expire and should be considered completed." + } + } + }, + "verificationPrefs": { + "type": "object", + "description": "Preferences for how verified accounts appear in the app.", + "required": [], + "properties": { + "hideBadges": { + "description": "Hide the blue check badges for verified accounts and trusted verifiers.", + "type": "boolean", + "default": false + } + } + }, + "liveEventPreferences": { + "type": "object", + "description": "Preferences for live events.", + "properties": { + "hiddenFeedIds": { + "description": "A list of feed IDs that the user has hidden from live events.", + "type": "array", + "items": { + "type": "string" + } + }, + "hideAllFeeds": { + "description": "Whether to hide all feeds from live events.", + "type": "boolean", + "default": false + } + } + }, + "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": [ + "app.bsky.feed.threadgate#mentionRule", + "app.bsky.feed.threadgate#followerRule", + "app.bsky.feed.threadgate#followingRule", + "app.bsky.feed.threadgate#listRule" + ] + } + }, + "postgateEmbeddingRules": { + "description": "Matches postgate record. List of rules defining who can embed this users posts. 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": ["app.bsky.feed.postgate#disableRule"] + } + } + } + }, + "statusView": { + "type": "object", + "required": ["status", "record"], + "properties": { + "uri": { + "type": "string", + "format": "at-uri" + }, + "cid": { + "type": "string", + "format": "cid" + }, + "status": { + "type": "string", + "description": "The status for the account.", + "knownValues": ["app.bsky.actor.status#live"] + }, + "record": { + "type": "unknown" + }, + "embed": { + "type": "union", + "description": "An optional embed associated with the status.", + "refs": ["app.bsky.embed.external#view"] + }, + "labels": { + "type": "array", + "items": { + "type": "ref", + "ref": "com.atproto.label.defs#label" + } + }, + "expiresAt": { + "type": "string", + "description": "The date when this status will expire. The application might choose to no longer return the status after expiration.", + "format": "datetime" + }, + "isActive": { + "type": "boolean", + "description": "True if the status is not expired, false if it is expired. Only present if expiration was set." + }, + "isDisabled": { + "type": "boolean", + "description": "True if the user's go-live access has been disabled by a moderator, false otherwise." + } + } + } + } +} diff --git a/lexicons/app/bsky/actor/getPreferences.json b/lexicons/app/bsky/actor/getPreferences.json new file mode 100644 index 0000000000..e6356a86f4 --- /dev/null +++ b/lexicons/app/bsky/actor/getPreferences.json @@ -0,0 +1,27 @@ +{ + "lexicon": 1, + "id": "app.bsky.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", + "required": ["preferences"], + "properties": { + "preferences": { + "type": "ref", + "ref": "app.bsky.actor.defs#preferences" + } + } + } + } + } + } +} diff --git a/lexicons/app/bsky/actor/getProfile.json b/lexicons/app/bsky/actor/getProfile.json new file mode 100644 index 0000000000..15b0fcc2ec --- /dev/null +++ b/lexicons/app/bsky/actor/getProfile.json @@ -0,0 +1,28 @@ +{ + "lexicon": 1, + "id": "app.bsky.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": "app.bsky.actor.defs#profileViewDetailed" + } + } + } + } +} diff --git a/lexicons/app/bsky/actor/getProfiles.json b/lexicons/app/bsky/actor/getProfiles.json new file mode 100644 index 0000000000..8691dac23b --- /dev/null +++ b/lexicons/app/bsky/actor/getProfiles.json @@ -0,0 +1,40 @@ +{ + "lexicon": 1, + "id": "app.bsky.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": "app.bsky.actor.defs#profileViewDetailed" + } + } + } + } + } + } + } +} diff --git a/lexicons/app/bsky/actor/getSuggestions.json b/lexicons/app/bsky/actor/getSuggestions.json new file mode 100644 index 0000000000..77ddfddf01 --- /dev/null +++ b/lexicons/app/bsky/actor/getSuggestions.json @@ -0,0 +1,51 @@ +{ + "lexicon": 1, + "id": "app.bsky.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": "app.bsky.actor.defs#profileView" + } + }, + "recId": { + "type": "integer", + "description": "DEPRECATED: use recIdStr instead." + }, + "recIdStr": { + "type": "string", + "description": "Snowflake for this recommendation, use when submitting recommendation events." + } + } + } + } + } + } +} diff --git a/lexicons/app/bsky/actor/profile.json b/lexicons/app/bsky/actor/profile.json new file mode 100644 index 0000000000..221b52bf84 --- /dev/null +++ b/lexicons/app/bsky/actor/profile.json @@ -0,0 +1,66 @@ +{ + "lexicon": 1, + "id": "app.bsky.actor.profile", + "defs": { + "main": { + "type": "record", + "description": "A declaration of a Bluesky 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 + }, + "pronouns": { + "type": "string", + "description": "Free-form pronouns text.", + "maxGraphemes": 20, + "maxLength": 200 + }, + "website": { + "type": "string", + "format": "uri" + }, + "avatar": { + "type": "blob", + "description": "Small image to be displayed next to posts from account. AKA, 'profile picture'", + "accept": ["image/png", "image/jpeg"], + "maxSize": 1000000 + }, + "banner": { + "type": "blob", + "description": "Larger horizontal image to display behind profile view.", + "accept": ["image/png", "image/jpeg"], + "maxSize": 1000000 + }, + "labels": { + "type": "union", + "description": "Self-label values, specific to the Bluesky application, on the overall account.", + "refs": ["com.atproto.label.defs#selfLabels"] + }, + "joinedViaStarterPack": { + "type": "ref", + "ref": "com.atproto.repo.strongRef" + }, + "pinnedPost": { + "type": "ref", + "ref": "com.atproto.repo.strongRef" + }, + "createdAt": { + "type": "string", + "format": "datetime" + } + } + } + } + } +} diff --git a/lexicons/app/bsky/actor/putPreferences.json b/lexicons/app/bsky/actor/putPreferences.json new file mode 100644 index 0000000000..425ea28c48 --- /dev/null +++ b/lexicons/app/bsky/actor/putPreferences.json @@ -0,0 +1,23 @@ +{ + "lexicon": 1, + "id": "app.bsky.actor.putPreferences", + "defs": { + "main": { + "type": "procedure", + "description": "Set the private preferences attached to the account.", + "input": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["preferences"], + "properties": { + "preferences": { + "type": "ref", + "ref": "app.bsky.actor.defs#preferences" + } + } + } + } + } + } +} diff --git a/lexicons/app/bsky/actor/searchActors.json b/lexicons/app/bsky/actor/searchActors.json new file mode 100644 index 0000000000..8eb4e16938 --- /dev/null +++ b/lexicons/app/bsky/actor/searchActors.json @@ -0,0 +1,51 @@ +{ + "lexicon": 1, + "id": "app.bsky.actor.searchActors", + "defs": { + "main": { + "type": "query", + "description": "Find actors (profiles) matching search criteria. Does not require auth.", + "parameters": { + "type": "params", + "properties": { + "term": { + "type": "string", + "description": "DEPRECATED: use 'q' instead." + }, + "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": "app.bsky.actor.defs#profileView" + } + } + } + } + } + } + } +} diff --git a/lexicons/app/bsky/actor/searchActorsTypeahead.json b/lexicons/app/bsky/actor/searchActorsTypeahead.json new file mode 100644 index 0000000000..4e3cb1b4e8 --- /dev/null +++ b/lexicons/app/bsky/actor/searchActorsTypeahead.json @@ -0,0 +1,45 @@ +{ + "lexicon": 1, + "id": "app.bsky.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": { + "term": { + "type": "string", + "description": "DEPRECATED: use 'q' instead." + }, + "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": "app.bsky.actor.defs#profileViewBasic" + } + } + } + } + } + } + } +} diff --git a/lexicons/app/bsky/actor/status.json b/lexicons/app/bsky/actor/status.json new file mode 100644 index 0000000000..647c10d118 --- /dev/null +++ b/lexicons/app/bsky/actor/status.json @@ -0,0 +1,40 @@ +{ + "lexicon": 1, + "id": "app.bsky.actor.status", + "defs": { + "main": { + "type": "record", + "description": "A declaration of a Bluesky account status.", + "key": "literal:self", + "record": { + "type": "object", + "required": ["status", "createdAt"], + "properties": { + "status": { + "type": "string", + "description": "The status for the account.", + "knownValues": ["app.bsky.actor.status#live"] + }, + "embed": { + "type": "union", + "description": "An optional embed associated with the status.", + "refs": ["app.bsky.embed.external"] + }, + "durationMinutes": { + "type": "integer", + "description": "The duration of the status in minutes. Applications can choose to impose minimum and maximum limits.", + "minimum": 1 + }, + "createdAt": { + "type": "string", + "format": "datetime" + } + } + } + }, + "live": { + "type": "token", + "description": "Advertises an account as currently offering live content." + } + } +} diff --git a/lexicons/app/bsky/ageassurance/begin.json b/lexicons/app/bsky/ageassurance/begin.json new file mode 100644 index 0000000000..13114c24e1 --- /dev/null +++ b/lexicons/app/bsky/ageassurance/begin.json @@ -0,0 +1,56 @@ +{ + "lexicon": 1, + "id": "app.bsky.ageassurance.begin", + "defs": { + "main": { + "type": "procedure", + "description": "Initiate Age Assurance for an account.", + "input": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["email", "language", "countryCode"], + "properties": { + "email": { + "type": "string", + "description": "The user's email address to receive Age Assurance instructions." + }, + "language": { + "type": "string", + "description": "The user's preferred language for communication during the Age Assurance process." + }, + "countryCode": { + "type": "string", + "description": "An ISO 3166-1 alpha-2 code of the user's location." + }, + "regionCode": { + "type": "string", + "description": "An optional ISO 3166-2 code of the user's region or state within the country." + } + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "ref", + "ref": "app.bsky.ageassurance.defs#state" + } + }, + "errors": [ + { + "name": "InvalidEmail" + }, + { + "name": "DidTooLong" + }, + { + "name": "InvalidInitiation" + }, + { + "name": "RegionNotSupported" + } + ] + } + } +} diff --git a/lexicons/app/bsky/ageassurance/defs.json b/lexicons/app/bsky/ageassurance/defs.json new file mode 100644 index 0000000000..8f3ee43448 --- /dev/null +++ b/lexicons/app/bsky/ageassurance/defs.json @@ -0,0 +1,263 @@ +{ + "lexicon": 1, + "id": "app.bsky.ageassurance.defs", + "defs": { + "access": { + "description": "The access level granted based on Age Assurance data we've processed.", + "type": "string", + "knownValues": ["unknown", "none", "safe", "full"] + }, + "status": { + "type": "string", + "description": "The status of the Age Assurance process.", + "knownValues": ["unknown", "pending", "assured", "blocked"] + }, + "state": { + "type": "object", + "description": "The user's computed Age Assurance state.", + "required": ["status", "access"], + "properties": { + "lastInitiatedAt": { + "type": "string", + "format": "datetime", + "description": "The timestamp when this state was last updated." + }, + "status": { + "type": "ref", + "ref": "app.bsky.ageassurance.defs#status" + }, + "access": { + "type": "ref", + "ref": "app.bsky.ageassurance.defs#access" + } + } + }, + "stateMetadata": { + "type": "object", + "description": "Additional metadata needed to compute Age Assurance state client-side.", + "required": [], + "properties": { + "accountCreatedAt": { + "type": "string", + "format": "datetime", + "description": "The account creation timestamp." + } + } + }, + "config": { + "type": "object", + "description": "", + "required": ["regions"], + "properties": { + "regions": { + "type": "array", + "description": "The per-region Age Assurance configuration.", + "items": { + "type": "ref", + "ref": "app.bsky.ageassurance.defs#configRegion" + } + } + } + }, + "configRegion": { + "type": "object", + "description": "The Age Assurance configuration for a specific region.", + "required": ["countryCode", "minAccessAge", "rules"], + "properties": { + "countryCode": { + "type": "string", + "description": "The ISO 3166-1 alpha-2 country code this configuration applies to." + }, + "regionCode": { + "type": "string", + "description": "The ISO 3166-2 region code this configuration applies to. If omitted, the configuration applies to the entire country." + }, + "minAccessAge": { + "type": "integer", + "description": "The minimum age (as a whole integer) required to use Bluesky in this region." + }, + "additionalVerificationMethods": { + "type": "array", + "description": "Verification methods permitted in this region in addition to the third-party (KWS) flow, which is always supported. `device` permits using the native on-device age APIs (e.g. Apple Declared Age Range, Google Play Age Signals).", + "items": { + "type": "string", + "knownValues": ["device"] + } + }, + "rules": { + "type": "array", + "description": "The ordered list of Age Assurance rules that apply to this region. Rules should be applied in order, and the first matching rule determines the access level granted. The rules array should always include a default rule as the last item.", + "items": { + "type": "union", + "refs": [ + "#configRegionRuleDefault", + "#configRegionRuleIfDeclaredOverAge", + "#configRegionRuleIfDeclaredUnderAge", + "#configRegionRuleIfAssuredOverAge", + "#configRegionRuleIfAssuredUnderAge", + "#configRegionRuleIfAccountNewerThan", + "#configRegionRuleIfAccountOlderThan" + ] + } + } + } + }, + "configRegionRuleDefault": { + "type": "object", + "description": "Age Assurance rule that applies by default.", + "required": ["access"], + "properties": { + "access": { + "type": "ref", + "ref": "app.bsky.ageassurance.defs#access" + } + } + }, + "configRegionRuleIfDeclaredOverAge": { + "type": "object", + "description": "Age Assurance rule that applies if the user has declared themselves equal-to or over a certain age.", + "required": ["age", "access"], + "properties": { + "age": { + "type": "integer", + "description": "The age threshold as a whole integer." + }, + "access": { + "type": "ref", + "ref": "app.bsky.ageassurance.defs#access" + } + } + }, + "configRegionRuleIfDeclaredUnderAge": { + "type": "object", + "description": "Age Assurance rule that applies if the user has declared themselves under a certain age.", + "required": ["age", "access"], + "properties": { + "age": { + "type": "integer", + "description": "The age threshold as a whole integer." + }, + "access": { + "type": "ref", + "ref": "app.bsky.ageassurance.defs#access" + } + } + }, + "configRegionRuleIfAssuredOverAge": { + "type": "object", + "description": "Age Assurance rule that applies if the user has been assured to be equal-to or over a certain age.", + "required": ["age", "access"], + "properties": { + "age": { + "type": "integer", + "description": "The age threshold as a whole integer." + }, + "access": { + "type": "ref", + "ref": "app.bsky.ageassurance.defs#access" + } + } + }, + "configRegionRuleIfAssuredUnderAge": { + "type": "object", + "description": "Age Assurance rule that applies if the user has been assured to be under a certain age.", + "required": ["age", "access"], + "properties": { + "age": { + "type": "integer", + "description": "The age threshold as a whole integer." + }, + "access": { + "type": "ref", + "ref": "app.bsky.ageassurance.defs#access" + } + } + }, + "configRegionRuleIfAccountNewerThan": { + "type": "object", + "description": "Age Assurance rule that applies if the account is equal-to or newer than a certain date.", + "required": ["date", "access"], + "properties": { + "date": { + "type": "string", + "format": "datetime", + "description": "The date threshold as a datetime string." + }, + "access": { + "type": "ref", + "ref": "app.bsky.ageassurance.defs#access" + } + } + }, + "configRegionRuleIfAccountOlderThan": { + "type": "object", + "description": "Age Assurance rule that applies if the account is older than a certain date.", + "required": ["date", "access"], + "properties": { + "date": { + "type": "string", + "format": "datetime", + "description": "The date threshold as a datetime string." + }, + "access": { + "type": "ref", + "ref": "app.bsky.ageassurance.defs#access" + } + } + }, + "event": { + "type": "object", + "description": "Object used to store Age Assurance data in stash.", + "required": ["createdAt", "status", "access", "attemptId", "countryCode"], + "properties": { + "createdAt": { + "type": "string", + "format": "datetime", + "description": "The date and time of this write operation." + }, + "attemptId": { + "type": "string", + "description": "The unique identifier for this instance of the Age Assurance flow, in UUID format." + }, + "status": { + "type": "string", + "description": "The status of the Age Assurance process.", + "knownValues": ["unknown", "pending", "assured", "blocked"] + }, + "access": { + "description": "The access level granted based on Age Assurance data we've processed.", + "type": "string", + "knownValues": ["unknown", "none", "safe", "full"] + }, + "countryCode": { + "type": "string", + "description": "The ISO 3166-1 alpha-2 country code provided when beginning the Age Assurance flow." + }, + "regionCode": { + "type": "string", + "description": "The ISO 3166-2 region code provided when beginning the Age Assurance flow." + }, + "email": { + "type": "string", + "description": "The email used for Age Assurance." + }, + "initIp": { + "type": "string", + "description": "The IP address used when initiating the Age Assurance flow." + }, + "initUa": { + "type": "string", + "description": "The user agent used when initiating the Age Assurance flow." + }, + "completeIp": { + "type": "string", + "description": "The IP address used when completing the Age Assurance flow." + }, + "completeUa": { + "type": "string", + "description": "The user agent used when completing the Age Assurance flow." + } + } + } + } +} diff --git a/lexicons/app/bsky/ageassurance/getConfig.json b/lexicons/app/bsky/ageassurance/getConfig.json new file mode 100644 index 0000000000..ca27af8da2 --- /dev/null +++ b/lexicons/app/bsky/ageassurance/getConfig.json @@ -0,0 +1,17 @@ +{ + "lexicon": 1, + "id": "app.bsky.ageassurance.getConfig", + "defs": { + "main": { + "type": "query", + "description": "Returns Age Assurance configuration for use on the client.", + "output": { + "encoding": "application/json", + "schema": { + "type": "ref", + "ref": "app.bsky.ageassurance.defs#config" + } + } + } + } +} diff --git a/lexicons/app/bsky/ageassurance/getState.json b/lexicons/app/bsky/ageassurance/getState.json new file mode 100644 index 0000000000..ac50f6f2a2 --- /dev/null +++ b/lexicons/app/bsky/ageassurance/getState.json @@ -0,0 +1,39 @@ +{ + "lexicon": 1, + "id": "app.bsky.ageassurance.getState", + "defs": { + "main": { + "type": "query", + "description": "Returns server-computed Age Assurance state, if available, and any additional metadata needed to compute Age Assurance state client-side.", + "parameters": { + "type": "params", + "required": ["countryCode"], + "properties": { + "countryCode": { + "type": "string" + }, + "regionCode": { + "type": "string" + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["state", "metadata"], + "properties": { + "state": { + "type": "ref", + "ref": "app.bsky.ageassurance.defs#state" + }, + "metadata": { + "type": "ref", + "ref": "app.bsky.ageassurance.defs#stateMetadata" + } + } + } + } + } + } +} diff --git a/lexicons/app/bsky/authCreatePosts.json b/lexicons/app/bsky/authCreatePosts.json new file mode 100644 index 0000000000..bc1db86083 --- /dev/null +++ b/lexicons/app/bsky/authCreatePosts.json @@ -0,0 +1,35 @@ +{ + "lexicon": 1, + "id": "app.bsky.authCreatePosts", + "defs": { + "main": { + "type": "permission-set", + "title": "Create Bluesky Posts", + "title:lang": {}, + "detail": "Can not update or delete posts.", + "detail:lang": {}, + "permissions": [ + { + "type": "permission", + "resource": "rpc", + "inheritAud": true, + "lxm": [ + "app.bsky.video.uploadVideo", + "app.bsky.video.getJobStatus", + "app.bsky.video.getUploadLimits" + ] + }, + { + "type": "permission", + "resource": "repo", + "action": ["create"], + "collection": [ + "app.bsky.feed.post", + "app.bsky.feed.postgate", + "app.bsky.feed.threadgate" + ] + } + ] + } + } +} diff --git a/lexicons/app/bsky/authDeleteContent.json b/lexicons/app/bsky/authDeleteContent.json new file mode 100644 index 0000000000..7fd3178303 --- /dev/null +++ b/lexicons/app/bsky/authDeleteContent.json @@ -0,0 +1,27 @@ +{ + "lexicon": 1, + "id": "app.bsky.authDeleteContent", + "defs": { + "main": { + "type": "permission-set", + "title": "Delete Bluesky Content", + "title:lang": {}, + "detail": "Clean up public account history: posts, reposts, and likes.", + "detail:lang": {}, + "permissions": [ + { + "type": "permission", + "resource": "repo", + "action": ["delete"], + "collection": [ + "app.bsky.feed.like", + "app.bsky.feed.post", + "app.bsky.feed.postgate", + "app.bsky.feed.repost", + "app.bsky.feed.threadgate" + ] + } + ] + } + } +} diff --git a/lexicons/app/bsky/authFullApp.json b/lexicons/app/bsky/authFullApp.json new file mode 100644 index 0000000000..9340ae1b94 --- /dev/null +++ b/lexicons/app/bsky/authFullApp.json @@ -0,0 +1,137 @@ +{ + "lexicon": 1, + "id": "app.bsky.authFullApp", + "defs": { + "main": { + "type": "permission-set", + "title": "Full Bluesky Social App Permissions", + "title:lang": {}, + "detail": "Manage all public content and interactions, private preferences and subscriptions, and other Bluesky-specific app features and data.", + "detail:lang": {}, + "permissions": [ + { + "type": "permission", + "resource": "rpc", + "inheritAud": true, + "lxm": [ + "app.bsky.actor.getPreferences", + "app.bsky.actor.getProfile", + "app.bsky.actor.getProfiles", + "app.bsky.actor.getSuggestions", + "app.bsky.actor.putPreferences", + "app.bsky.actor.searchActors", + "app.bsky.actor.searchActorsTypeahead", + "app.bsky.bookmark.createBookmark", + "app.bsky.bookmark.deleteBookmark", + "app.bsky.bookmark.getBookmarks", + "app.bsky.contact.dismissMatch", + "app.bsky.contact.getMatches", + "app.bsky.contact.getSyncStatus", + "app.bsky.contact.importContacts", + "app.bsky.contact.removeData", + "app.bsky.contact.startPhoneVerification", + "app.bsky.contact.verifyPhone", + "app.bsky.feed.describeFeedGenerator", + "app.bsky.feed.getActorFeeds", + "app.bsky.feed.getActorLikes", + "app.bsky.feed.getAuthorFeed", + "app.bsky.feed.getFeed", + "app.bsky.feed.getFeedGenerator", + "app.bsky.feed.getFeedGenerators", + "app.bsky.feed.getFeedSkeleton", + "app.bsky.feed.getLikes", + "app.bsky.feed.getListFeed", + "app.bsky.feed.getPostThread", + "app.bsky.feed.getPosts", + "app.bsky.feed.getQuotes", + "app.bsky.feed.getRepostedBy", + "app.bsky.feed.getSuggestedFeeds", + "app.bsky.feed.getTimeline", + "app.bsky.feed.searchPosts", + "app.bsky.feed.searchPostsV2", + "app.bsky.feed.sendInteractions", + "app.bsky.graph.getActorStarterPacks", + "app.bsky.graph.getBlocks", + "app.bsky.graph.getFollowers", + "app.bsky.graph.getFollows", + "app.bsky.graph.getKnownFollowers", + "app.bsky.graph.getList", + "app.bsky.graph.getListBlocks", + "app.bsky.graph.getListMutes", + "app.bsky.graph.getLists", + "app.bsky.graph.getListsWithMembership", + "app.bsky.graph.getMutes", + "app.bsky.graph.getRelationships", + "app.bsky.graph.getStarterPack", + "app.bsky.graph.getStarterPacks", + "app.bsky.graph.getStarterPacksWithMembership", + "app.bsky.graph.getSuggestedFollowsByActor", + "app.bsky.graph.muteActor", + "app.bsky.graph.muteActorList", + "app.bsky.graph.muteThread", + "app.bsky.graph.searchStarterPacks", + "app.bsky.graph.unmuteActor", + "app.bsky.graph.unmuteActorList", + "app.bsky.graph.unmuteThread", + "app.bsky.labeler.getServices", + "app.bsky.notification.getPreferences", + "app.bsky.notification.getUnreadCount", + "app.bsky.notification.listActivitySubscriptions", + "app.bsky.notification.listNotifications", + "app.bsky.notification.putActivitySubscription", + "app.bsky.notification.putPreferences", + "app.bsky.notification.putPreferencesV2", + "app.bsky.notification.registerPush", + "app.bsky.notification.unregisterPush", + "app.bsky.notification.updateSeen", + "app.bsky.unspecced.getAgeAssuranceState", + "app.bsky.unspecced.getConfig", + "app.bsky.unspecced.getOnboardingSuggestedStarterPacks", + "app.bsky.unspecced.getPopularFeedGenerators", + "app.bsky.unspecced.getPostThreadOtherV2", + "app.bsky.unspecced.getPostThreadV2", + "app.bsky.unspecced.getSuggestedFeeds", + "app.bsky.unspecced.getSuggestedFeedsSkeleton", + "app.bsky.unspecced.getSuggestedStarterPacks", + "app.bsky.unspecced.getSuggestedStarterPacksSkeleton", + "app.bsky.unspecced.getSuggestedUsers", + "app.bsky.unspecced.getSuggestedUsersSkeleton", + "app.bsky.unspecced.getSuggestionsSkeleton", + "app.bsky.unspecced.getTaggedSuggestions", + "app.bsky.unspecced.getTrendingTopics", + "app.bsky.unspecced.getTrends", + "app.bsky.unspecced.getTrendsSkeleton", + "app.bsky.unspecced.initAgeAssurance", + "app.bsky.unspecced.searchActorsSkeleton", + "app.bsky.unspecced.searchPostsSkeleton", + "app.bsky.unspecced.searchStarterPacksSkeleton", + "app.bsky.video.getJobStatus", + "app.bsky.video.getUploadLimits", + "app.bsky.video.uploadVideo" + ] + }, + { + "type": "permission", + "resource": "repo", + "action": ["create", "update", "delete"], + "collection": [ + "app.bsky.actor.profile", + "app.bsky.actor.status", + "app.bsky.feed.like", + "app.bsky.feed.post", + "app.bsky.feed.postgate", + "app.bsky.feed.repost", + "app.bsky.feed.threadgate", + "app.bsky.graph.block", + "app.bsky.graph.follow", + "app.bsky.graph.list", + "app.bsky.graph.listblock", + "app.bsky.graph.listitem", + "app.bsky.graph.starterpack", + "app.bsky.notification.declaration" + ] + } + ] + } + } +} diff --git a/lexicons/app/bsky/authManageFeedDeclarations.json b/lexicons/app/bsky/authManageFeedDeclarations.json new file mode 100644 index 0000000000..a94600a1fe --- /dev/null +++ b/lexicons/app/bsky/authManageFeedDeclarations.json @@ -0,0 +1,21 @@ +{ + "lexicon": 1, + "id": "app.bsky.authManageFeedDeclarations", + "defs": { + "main": { + "type": "permission-set", + "title": "Manage Hosted Feeds", + "title:lang": {}, + "detail": "Configure feed generator declaration records.", + "detail:lang": {}, + "permissions": [ + { + "type": "permission", + "resource": "repo", + "action": ["create", "update", "delete"], + "collection": ["app.bsky.feed.generator"] + } + ] + } + } +} diff --git a/lexicons/app/bsky/authManageLabelerService.json b/lexicons/app/bsky/authManageLabelerService.json new file mode 100644 index 0000000000..3ccc243f8e --- /dev/null +++ b/lexicons/app/bsky/authManageLabelerService.json @@ -0,0 +1,21 @@ +{ + "lexicon": 1, + "id": "app.bsky.authManageLabelerService", + "defs": { + "main": { + "type": "permission-set", + "title": "Manage Hosted Labeling Service", + "title:lang": {}, + "detail": "Configure labeler declaration records.", + "detail:lang": {}, + "permissions": [ + { + "type": "permission", + "resource": "repo", + "action": ["create", "update", "delete"], + "collection": ["app.bsky.labeler.service"] + } + ] + } + } +} diff --git a/lexicons/app/bsky/authManageModeration.json b/lexicons/app/bsky/authManageModeration.json new file mode 100644 index 0000000000..8b8c252e53 --- /dev/null +++ b/lexicons/app/bsky/authManageModeration.json @@ -0,0 +1,36 @@ +{ + "lexicon": 1, + "id": "app.bsky.authManageModeration", + "defs": { + "main": { + "type": "permission-set", + "title": "Manage Personal Moderation", + "title:lang": {}, + "detail": "Control over blocks, mutes, mod lists, mod services, and preferences.", + "detail:lang": {}, + "permissions": [ + { + "type": "permission", + "resource": "rpc", + "inheritAud": true, + "lxm": [ + "app.bsky.actor.getPreferences", + "app.bsky.actor.putPreferences", + "app.bsky.graph.muteActor", + "app.bsky.graph.muteActorList", + "app.bsky.graph.muteThread", + "app.bsky.graph.unmuteActor", + "app.bsky.graph.unmuteActorList", + "app.bsky.graph.unmuteThread" + ] + }, + { + "type": "permission", + "resource": "repo", + "action": ["create", "update", "delete"], + "collection": ["app.bsky.graph.block", "app.bsky.graph.listblock"] + } + ] + } + } +} diff --git a/lexicons/app/bsky/authManageNotifications.json b/lexicons/app/bsky/authManageNotifications.json new file mode 100644 index 0000000000..767353d4a0 --- /dev/null +++ b/lexicons/app/bsky/authManageNotifications.json @@ -0,0 +1,32 @@ +{ + "lexicon": 1, + "id": "app.bsky.authManageNotifications", + "defs": { + "main": { + "type": "permission-set", + "title": "Manage Bluesky Notifications", + "title:lang": {}, + "detail": "View and configure notifications for the Bluesky app.", + "detail:lang": {}, + "permissions": [ + { + "type": "permission", + "resource": "rpc", + "inheritAud": true, + "lxm": [ + "app.bsky.notification.getPreferences", + "app.bsky.notification.getUnreadCount", + "app.bsky.notification.listActivitySubscriptions", + "app.bsky.notification.listNotifications", + "app.bsky.notification.putActivitySubscription", + "app.bsky.notification.putPreferences", + "app.bsky.notification.putPreferencesV2", + "app.bsky.notification.registerPush", + "app.bsky.notification.unregisterPush", + "app.bsky.notification.updateSeen" + ] + } + ] + } + } +} diff --git a/lexicons/app/bsky/authManageProfile.json b/lexicons/app/bsky/authManageProfile.json new file mode 100644 index 0000000000..ccf4aea6ed --- /dev/null +++ b/lexicons/app/bsky/authManageProfile.json @@ -0,0 +1,25 @@ +{ + "lexicon": 1, + "id": "app.bsky.authManageProfile", + "defs": { + "main": { + "type": "permission-set", + "title": "Manage Bluesky Profile", + "title:lang": {}, + "detail": "Update profile data, as well as status and public chat visibility.", + "detail:lang": {}, + "permissions": [ + { + "type": "permission", + "resource": "repo", + "action": ["create", "update", "delete"], + "collection": [ + "app.bsky.actor.profile", + "app.bsky.actor.status", + "app.bsky.notification.declaration" + ] + } + ] + } + } +} diff --git a/lexicons/app/bsky/authViewAll.json b/lexicons/app/bsky/authViewAll.json new file mode 100644 index 0000000000..62d34021fd --- /dev/null +++ b/lexicons/app/bsky/authViewAll.json @@ -0,0 +1,90 @@ +{ + "lexicon": 1, + "id": "app.bsky.authViewAll", + "defs": { + "main": { + "type": "permission-set", + "title": "Read-only access to all content", + "title:lang": {}, + "detail": "View Bluesky network content from account perspective, and read all notifications and preferences.", + "detail:lang": {}, + "permissions": [ + { + "type": "permission", + "resource": "rpc", + "inheritAud": true, + "lxm": [ + "app.bsky.actor.getPreferences", + "app.bsky.actor.getProfile", + "app.bsky.actor.getProfiles", + "app.bsky.actor.getSuggestions", + "app.bsky.actor.searchActors", + "app.bsky.actor.searchActorsTypeahead", + "app.bsky.bookmark.getBookmarks", + "app.bsky.feed.describeFeedGenerator", + "app.bsky.feed.getActorFeeds", + "app.bsky.feed.getActorLikes", + "app.bsky.feed.getAuthorFeed", + "app.bsky.feed.getFeed", + "app.bsky.feed.getFeedGenerator", + "app.bsky.feed.getFeedGenerators", + "app.bsky.feed.getFeedSkeleton", + "app.bsky.feed.getLikes", + "app.bsky.feed.getListFeed", + "app.bsky.feed.getPostThread", + "app.bsky.feed.getPosts", + "app.bsky.feed.getQuotes", + "app.bsky.feed.getRepostedBy", + "app.bsky.feed.getSuggestedFeeds", + "app.bsky.feed.getTimeline", + "app.bsky.feed.searchPosts", + "app.bsky.feed.searchPostsV2", + "app.bsky.graph.getActorStarterPacks", + "app.bsky.graph.getBlocks", + "app.bsky.graph.getFollowers", + "app.bsky.graph.getFollows", + "app.bsky.graph.getKnownFollowers", + "app.bsky.graph.getListBlocks", + "app.bsky.graph.getListMutes", + "app.bsky.graph.getLists", + "app.bsky.graph.getListsWithMembership", + "app.bsky.graph.getMutes", + "app.bsky.graph.getRelationships", + "app.bsky.graph.getStarterPack", + "app.bsky.graph.getStarterPacks", + "app.bsky.graph.getStarterPacksWithMembership", + "app.bsky.graph.getSuggestedFollowsByActor", + "app.bsky.graph.searchStarterPacks", + "app.bsky.labeler.getServices", + "app.bsky.notification.getPreferences", + "app.bsky.notification.getUnreadCount", + "app.bsky.notification.listActivitySubscriptions", + "app.bsky.notification.listNotifications", + "app.bsky.notification.updateSeen", + "app.bsky.unspecced.getAgeAssuranceState", + "app.bsky.unspecced.getConfig", + "app.bsky.unspecced.getOnboardingSuggestedStarterPacks", + "app.bsky.unspecced.getPopularFeedGenerators", + "app.bsky.unspecced.getPostThreadOtherV2", + "app.bsky.unspecced.getPostThreadV2", + "app.bsky.unspecced.getSuggestedFeeds", + "app.bsky.unspecced.getSuggestedFeedsSkeleton", + "app.bsky.unspecced.getSuggestedStarterPacks", + "app.bsky.unspecced.getSuggestedStarterPacksSkeleton", + "app.bsky.unspecced.getSuggestedUsers", + "app.bsky.unspecced.getSuggestedUsersSkeleton", + "app.bsky.unspecced.getSuggestionsSkeleton", + "app.bsky.unspecced.getTaggedSuggestions", + "app.bsky.unspecced.getTrendingTopics", + "app.bsky.unspecced.getTrends", + "app.bsky.unspecced.getTrendsSkeleton", + "app.bsky.unspecced.searchActorsSkeleton", + "app.bsky.unspecced.searchPostsSkeleton", + "app.bsky.unspecced.searchStarterPacksSkeleton", + "app.bsky.video.getUploadLimits" + ] + } + ] + } + } +} diff --git a/lexicons/app/bsky/bookmark/createBookmark.json b/lexicons/app/bsky/bookmark/createBookmark.json new file mode 100644 index 0000000000..d4799548f3 --- /dev/null +++ b/lexicons/app/bsky/bookmark/createBookmark.json @@ -0,0 +1,33 @@ +{ + "lexicon": 1, + "id": "app.bsky.bookmark.createBookmark", + "defs": { + "main": { + "type": "procedure", + "description": "Creates a private bookmark for the specified record. Currently, only `app.bsky.feed.post` records are supported. Requires authentication.", + "input": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["uri", "cid"], + "properties": { + "uri": { + "type": "string", + "format": "at-uri" + }, + "cid": { + "type": "string", + "format": "cid" + } + } + } + }, + "errors": [ + { + "name": "UnsupportedCollection", + "description": "The URI to be bookmarked is for an unsupported collection." + } + ] + } + } +} diff --git a/lexicons/app/bsky/bookmark/defs.json b/lexicons/app/bsky/bookmark/defs.json new file mode 100644 index 0000000000..d4d6dda235 --- /dev/null +++ b/lexicons/app/bsky/bookmark/defs.json @@ -0,0 +1,41 @@ +{ + "lexicon": 1, + "id": "app.bsky.bookmark.defs", + "defs": { + "bookmark": { + "description": "Object used to store bookmark data in stash.", + "type": "object", + "required": ["subject"], + "properties": { + "subject": { + "description": "A strong ref to the record to be bookmarked. Currently, only `app.bsky.feed.post` records are supported.", + "type": "ref", + "ref": "com.atproto.repo.strongRef" + } + } + }, + "bookmarkView": { + "type": "object", + "required": ["subject", "item"], + "properties": { + "subject": { + "description": "A strong ref to the bookmarked record.", + "type": "ref", + "ref": "com.atproto.repo.strongRef" + }, + "createdAt": { + "type": "string", + "format": "datetime" + }, + "item": { + "type": "union", + "refs": [ + "app.bsky.feed.defs#blockedPost", + "app.bsky.feed.defs#notFoundPost", + "app.bsky.feed.defs#postView" + ] + } + } + } + } +} diff --git a/lexicons/app/bsky/bookmark/deleteBookmark.json b/lexicons/app/bsky/bookmark/deleteBookmark.json new file mode 100644 index 0000000000..354f84d777 --- /dev/null +++ b/lexicons/app/bsky/bookmark/deleteBookmark.json @@ -0,0 +1,29 @@ +{ + "lexicon": 1, + "id": "app.bsky.bookmark.deleteBookmark", + "defs": { + "main": { + "type": "procedure", + "description": "Deletes a private bookmark for the specified record. Currently, only `app.bsky.feed.post` records are supported. Requires authentication.", + "input": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["uri"], + "properties": { + "uri": { + "type": "string", + "format": "at-uri" + } + } + } + }, + "errors": [ + { + "name": "UnsupportedCollection", + "description": "The URI to be bookmarked is for an unsupported collection." + } + ] + } + } +} diff --git a/lexicons/app/bsky/bookmark/getBookmarks.json b/lexicons/app/bsky/bookmark/getBookmarks.json new file mode 100644 index 0000000000..08c4fd5938 --- /dev/null +++ b/lexicons/app/bsky/bookmark/getBookmarks.json @@ -0,0 +1,43 @@ +{ + "lexicon": 1, + "id": "app.bsky.bookmark.getBookmarks", + "defs": { + "main": { + "type": "query", + "description": "Gets views of records bookmarked by the authenticated user. Requires authentication.", + "parameters": { + "type": "params", + "properties": { + "limit": { + "type": "integer", + "minimum": 1, + "maximum": 100, + "default": 50 + }, + "cursor": { + "type": "string" + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["bookmarks"], + "properties": { + "cursor": { + "type": "string" + }, + "bookmarks": { + "type": "array", + "items": { + "type": "ref", + "ref": "app.bsky.bookmark.defs#bookmarkView" + } + } + } + } + } + } + } +} diff --git a/lexicons/app/bsky/contact/defs.json b/lexicons/app/bsky/contact/defs.json new file mode 100644 index 0000000000..5705814e3e --- /dev/null +++ b/lexicons/app/bsky/contact/defs.json @@ -0,0 +1,57 @@ +{ + "lexicon": 1, + "id": "app.bsky.contact.defs", + "defs": { + "matchAndContactIndex": { + "description": "Associates a profile with the positional index of the contact import input in the call to `app.bsky.contact.importContacts`, so clients can know which phone caused a particular match.", + "type": "object", + "required": ["match", "contactIndex"], + "properties": { + "match": { + "description": "Profile of the matched user.", + "type": "ref", + "ref": "app.bsky.actor.defs#profileView" + }, + "contactIndex": { + "description": "The index of this match in the import contact input.", + "type": "integer", + "minimum": 0, + "maximum": 999 + } + } + }, + "syncStatus": { + "type": "object", + "required": ["syncedAt", "matchesCount"], + "properties": { + "syncedAt": { + "description": "Last date when contacts where imported.", + "type": "string", + "format": "datetime" + }, + "matchesCount": { + "description": "Number of existing contact matches resulting of the user imports and of their imported contacts having imported the user. Matches stop being counted when the user either follows the matched contact or dismisses the match.", + "type": "integer", + "minimum": 0 + } + } + }, + "notification": { + "description": "A stash object to be sent via bsync representing a notification to be created.", + "type": "object", + "required": ["from", "to"], + "properties": { + "from": { + "description": "The DID of who this notification comes from.", + "type": "string", + "format": "did" + }, + "to": { + "description": "The DID of who this notification should go to.", + "type": "string", + "format": "did" + } + } + } + } +} diff --git a/lexicons/app/bsky/contact/dismissMatch.json b/lexicons/app/bsky/contact/dismissMatch.json new file mode 100644 index 0000000000..66503ce2bf --- /dev/null +++ b/lexicons/app/bsky/contact/dismissMatch.json @@ -0,0 +1,39 @@ +{ + "lexicon": 1, + "id": "app.bsky.contact.dismissMatch", + "defs": { + "main": { + "type": "procedure", + "description": "Removes a match that was found via contact import. It shouldn't appear again if the same contact is re-imported. Requires authentication.", + "input": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["subject"], + "properties": { + "subject": { + "description": "The subject's DID to dismiss the match with.", + "type": "string", + "format": "did" + } + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "properties": {} + } + }, + "errors": [ + { + "name": "InvalidDid" + }, + { + "name": "InternalError" + } + ] + } + } +} diff --git a/lexicons/app/bsky/contact/getMatches.json b/lexicons/app/bsky/contact/getMatches.json new file mode 100644 index 0000000000..2fca12c152 --- /dev/null +++ b/lexicons/app/bsky/contact/getMatches.json @@ -0,0 +1,57 @@ +{ + "lexicon": 1, + "id": "app.bsky.contact.getMatches", + "defs": { + "main": { + "type": "query", + "description": "Returns the matched contacts (contacts that were mutually imported). Excludes dismissed matches. Requires authentication.", + "parameters": { + "type": "params", + "properties": { + "limit": { + "type": "integer", + "minimum": 1, + "maximum": 100, + "default": 50 + }, + "cursor": { + "type": "string" + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["matches"], + "properties": { + "cursor": { + "type": "string" + }, + "matches": { + "type": "array", + "items": { + "type": "ref", + "ref": "app.bsky.actor.defs#profileView" + } + } + } + } + }, + "errors": [ + { + "name": "InvalidDid" + }, + { + "name": "InvalidLimit" + }, + { + "name": "InvalidCursor" + }, + { + "name": "InternalError" + } + ] + } + } +} diff --git a/lexicons/app/bsky/contact/getSyncStatus.json b/lexicons/app/bsky/contact/getSyncStatus.json new file mode 100644 index 0000000000..03fee0027c --- /dev/null +++ b/lexicons/app/bsky/contact/getSyncStatus.json @@ -0,0 +1,35 @@ +{ + "lexicon": 1, + "id": "app.bsky.contact.getSyncStatus", + "defs": { + "main": { + "type": "query", + "description": "Gets the user's current contact import status. Requires authentication.", + "parameters": { + "type": "params", + "properties": {} + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "properties": { + "syncStatus": { + "description": "If present, indicates the user has imported their contacts. If not present, indicates the user never used the feature or called `app.bsky.contact.removeData` and didn't import again since.", + "type": "ref", + "ref": "app.bsky.contact.defs#syncStatus" + } + } + } + }, + "errors": [ + { + "name": "InvalidDid" + }, + { + "name": "InternalError" + } + ] + } + } +} diff --git a/lexicons/app/bsky/contact/importContacts.json b/lexicons/app/bsky/contact/importContacts.json new file mode 100644 index 0000000000..ac7449b751 --- /dev/null +++ b/lexicons/app/bsky/contact/importContacts.json @@ -0,0 +1,66 @@ +{ + "lexicon": 1, + "id": "app.bsky.contact.importContacts", + "defs": { + "main": { + "type": "procedure", + "description": "Import contacts for securely matching with other users. This follows the protocol explained in https://docs.bsky.app/blog/contact-import-rfc. Requires authentication.", + "input": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["token", "contacts"], + "properties": { + "token": { + "description": "JWT to authenticate the call. Use the JWT received as a response to the call to `app.bsky.contact.verifyPhone`.", + "type": "string" + }, + "contacts": { + "description": "List of phone numbers in global E.164 format (e.g., '+12125550123'). Phone numbers that cannot be normalized into a valid phone number will be discarded. Should not repeat the 'phone' input used in `app.bsky.contact.verifyPhone`.", + "type": "array", + "items": { + "type": "string" + }, + "minLength": 1, + "maxLength": 1000 + } + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["matchesAndContactIndexes"], + "properties": { + "matchesAndContactIndexes": { + "description": "The users that matched during import and their indexes on the input contacts, so the client can correlate with its local list.", + "type": "array", + "items": { + "type": "ref", + "ref": "app.bsky.contact.defs#matchAndContactIndex" + } + } + } + } + }, + "errors": [ + { + "name": "InvalidDid" + }, + { + "name": "InvalidContacts" + }, + { + "name": "TooManyContacts" + }, + { + "name": "InvalidToken" + }, + { + "name": "InternalError" + } + ] + } + } +} diff --git a/lexicons/app/bsky/contact/removeData.json b/lexicons/app/bsky/contact/removeData.json new file mode 100644 index 0000000000..56dd911ee4 --- /dev/null +++ b/lexicons/app/bsky/contact/removeData.json @@ -0,0 +1,32 @@ +{ + "lexicon": 1, + "id": "app.bsky.contact.removeData", + "defs": { + "main": { + "type": "procedure", + "description": "Removes all stored hashes used for contact matching, existing matches, and sync status. Requires authentication.", + "input": { + "encoding": "application/json", + "schema": { + "type": "object", + "properties": {} + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "properties": {} + } + }, + "errors": [ + { + "name": "InvalidDid" + }, + { + "name": "InternalError" + } + ] + } + } +} diff --git a/lexicons/app/bsky/contact/sendNotification.json b/lexicons/app/bsky/contact/sendNotification.json new file mode 100644 index 0000000000..74af1a0107 --- /dev/null +++ b/lexicons/app/bsky/contact/sendNotification.json @@ -0,0 +1,36 @@ +{ + "lexicon": 1, + "id": "app.bsky.contact.sendNotification", + "defs": { + "main": { + "type": "procedure", + "description": "System endpoint to send notifications related to contact imports. Requires role authentication.", + "input": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["from", "to"], + "properties": { + "from": { + "description": "The DID of who this notification comes from.", + "type": "string", + "format": "did" + }, + "to": { + "description": "The DID of who this notification should go to.", + "type": "string", + "format": "did" + } + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "properties": {} + } + } + } + } +} diff --git a/lexicons/app/bsky/contact/startPhoneVerification.json b/lexicons/app/bsky/contact/startPhoneVerification.json new file mode 100644 index 0000000000..b11024cbe0 --- /dev/null +++ b/lexicons/app/bsky/contact/startPhoneVerification.json @@ -0,0 +1,44 @@ +{ + "lexicon": 1, + "id": "app.bsky.contact.startPhoneVerification", + "defs": { + "main": { + "type": "procedure", + "description": "Starts a phone verification flow. The phone passed will receive a code via SMS that should be passed to `app.bsky.contact.verifyPhone`. Requires authentication.", + "input": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["phone"], + "properties": { + "phone": { + "description": "The phone number to receive the code via SMS.", + "type": "string" + } + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "properties": {} + } + }, + "errors": [ + { + "name": "RateLimitExceeded" + }, + { + "name": "InvalidDid" + }, + { + "name": "InvalidPhone" + }, + { + "name": "InternalError" + } + ] + } + } +} diff --git a/lexicons/app/bsky/contact/verifyPhone.json b/lexicons/app/bsky/contact/verifyPhone.json new file mode 100644 index 0000000000..fed072eea3 --- /dev/null +++ b/lexicons/app/bsky/contact/verifyPhone.json @@ -0,0 +1,57 @@ +{ + "lexicon": 1, + "id": "app.bsky.contact.verifyPhone", + "defs": { + "main": { + "type": "procedure", + "description": "Verifies control over a phone number with a code received via SMS and starts a contact import session. Requires authentication.", + "input": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["phone", "code"], + "properties": { + "phone": { + "description": "The phone number to verify. Should be the same as the one passed to `app.bsky.contact.startPhoneVerification`.", + "type": "string" + }, + "code": { + "description": "The code received via SMS as a result of the call to `app.bsky.contact.startPhoneVerification`.", + "type": "string" + } + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["token"], + "properties": { + "token": { + "description": "JWT to be used in a call to `app.bsky.contact.importContacts`. It is only valid for a single call.", + "type": "string" + } + } + } + }, + "errors": [ + { + "name": "RateLimitExceeded" + }, + { + "name": "InvalidDid" + }, + { + "name": "InvalidPhone" + }, + { + "name": "InvalidCode" + }, + { + "name": "InternalError" + } + ] + } + } +} diff --git a/lexicons/app/bsky/draft/createDraft.json b/lexicons/app/bsky/draft/createDraft.json new file mode 100644 index 0000000000..d18239d85e --- /dev/null +++ b/lexicons/app/bsky/draft/createDraft.json @@ -0,0 +1,42 @@ +{ + "lexicon": 1, + "id": "app.bsky.draft.createDraft", + "defs": { + "main": { + "type": "procedure", + "description": "Inserts a draft using private storage (stash). An upper limit of drafts might be enforced. Requires authentication.", + "input": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["draft"], + "properties": { + "draft": { + "type": "ref", + "ref": "app.bsky.draft.defs#draft" + } + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["id"], + "properties": { + "id": { + "type": "string", + "description": "The ID of the created draft." + } + } + } + }, + "errors": [ + { + "name": "DraftLimitReached", + "description": "Trying to insert a new draft when the limit was already reached." + } + ] + } + } +} diff --git a/lexicons/app/bsky/draft/defs.json b/lexicons/app/bsky/draft/defs.json new file mode 100644 index 0000000000..3656621377 --- /dev/null +++ b/lexicons/app/bsky/draft/defs.json @@ -0,0 +1,262 @@ +{ + "lexicon": 1, + "id": "app.bsky.draft.defs", + "defs": { + "draftWithId": { + "description": "A draft with an identifier, used to store drafts in private storage (stash).", + "type": "object", + "required": ["id", "draft"], + "properties": { + "id": { + "description": "A TID to be used as a draft identifier.", + "type": "string", + "format": "tid" + }, + "draft": { + "type": "ref", + "ref": "#draft" + } + } + }, + "draft": { + "description": "A draft containing an array of draft posts.", + "type": "object", + "required": ["posts"], + "properties": { + "deviceId": { + "type": "string", + "description": "UUIDv4 identifier of the device that created this draft.", + "maxLength": 100 + }, + "deviceName": { + "type": "string", + "description": "The device and/or platform on which the draft was created.", + "maxLength": 100 + }, + "posts": { + "description": "Array of draft posts that compose this draft.", + "type": "array", + "minLength": 1, + "maxLength": 100, + "items": { + "type": "ref", + "ref": "#draftPost" + } + }, + "langs": { + "type": "array", + "description": "Indicates human language of posts primary text content.", + "maxLength": 3, + "items": { + "type": "string", + "format": "language" + } + }, + "postgateEmbeddingRules": { + "description": "Embedding rules for the postgates to be created when this draft is published.", + "type": "array", + "maxLength": 5, + "items": { + "type": "union", + "refs": ["app.bsky.feed.postgate#disableRule"] + } + }, + "threadgateAllow": { + "description": "Allow-rules for the threadgate to be created when this draft is published.", + "type": "array", + "maxLength": 5, + "items": { + "type": "union", + "refs": [ + "app.bsky.feed.threadgate#mentionRule", + "app.bsky.feed.threadgate#followerRule", + "app.bsky.feed.threadgate#followingRule", + "app.bsky.feed.threadgate#listRule" + ] + } + } + } + }, + "draftPost": { + "description": "One of the posts that compose a draft.", + "type": "object", + "required": ["text"], + "properties": { + "text": { + "type": "string", + "maxLength": 10000, + "maxGraphemes": 1000, + "description": "The primary post content. It has a higher limit than post contents to allow storing a larger text that can later be refined into smaller posts." + }, + "labels": { + "type": "union", + "description": "Self-label values for this post. Effectively content warnings.", + "refs": ["com.atproto.label.defs#selfLabels"] + }, + "embedImages": { + "type": "array", + "items": { + "type": "ref", + "ref": "#draftEmbedImage" + }, + "maxLength": 4 + }, + "embedGallery": { + "type": "ref", + "ref": "#draftEmbedGallery" + }, + "embedVideos": { + "type": "array", + "items": { + "type": "ref", + "ref": "#draftEmbedVideo" + }, + "maxLength": 1 + }, + "embedExternals": { + "type": "array", + "items": { + "type": "ref", + "ref": "#draftEmbedExternal" + }, + "maxLength": 1 + }, + "embedRecords": { + "type": "array", + "items": { + "type": "ref", + "ref": "#draftEmbedRecord" + }, + "maxLength": 1 + } + } + }, + "draftView": { + "description": "View to present drafts data to users.", + "type": "object", + "required": ["id", "draft", "createdAt", "updatedAt"], + "properties": { + "id": { + "description": "A TID to be used as a draft identifier.", + "type": "string", + "format": "tid" + }, + "draft": { + "type": "ref", + "ref": "#draft" + }, + "createdAt": { + "description": "The time the draft was created.", + "type": "string", + "format": "datetime" + }, + "updatedAt": { + "description": "The time the draft was last updated.", + "type": "string", + "format": "datetime" + } + } + }, + "draftEmbedLocalRef": { + "type": "object", + "required": ["path"], + "properties": { + "path": { + "type": "string", + "description": "Local, on-device ref to file to be embedded. Embeds are currently device-bound for drafts.", + "minLength": 1, + "maxLength": 1024 + } + } + }, + "draftEmbedCaption": { + "type": "object", + "required": ["lang", "content"], + "properties": { + "lang": { + "type": "string", + "format": "language" + }, + "content": { + "type": "string", + "maxLength": 10000 + } + } + }, + "draftEmbedGallery": { + "type": "object", + "required": ["items"], + "properties": { + "items": { + "type": "ref", + "ref": "#draftEmbedGalleryItems" + } + } + }, + "draftEmbedGalleryItems": { + "type": "array", + "items": { + "type": "union", + "refs": ["#draftEmbedImage"] + }, + "maxLength": 20, + "description": "The schema-level maxLength of 20 is a future-proof ceiling. Clients should currently enforce a soft limit of 10 items in authoring UIs." + }, + "draftEmbedImage": { + "type": "object", + "required": ["localRef"], + "properties": { + "localRef": { + "type": "ref", + "ref": "#draftEmbedLocalRef" + }, + "alt": { + "type": "string", + "maxGraphemes": 2000 + } + } + }, + "draftEmbedVideo": { + "type": "object", + "required": ["localRef"], + "properties": { + "localRef": { + "type": "ref", + "ref": "#draftEmbedLocalRef" + }, + "alt": { + "type": "string", + "maxGraphemes": 2000 + }, + "captions": { + "type": "array", + "items": { + "type": "ref", + "ref": "#draftEmbedCaption" + }, + "maxLength": 20 + } + } + }, + "draftEmbedExternal": { + "type": "object", + "required": ["uri"], + "properties": { + "uri": { + "type": "string", + "format": "uri" + } + } + }, + "draftEmbedRecord": { + "type": "object", + "required": ["record"], + "properties": { + "record": { + "type": "ref", + "ref": "com.atproto.repo.strongRef" + } + } + } + } +} diff --git a/lexicons/app/bsky/draft/deleteDraft.json b/lexicons/app/bsky/draft/deleteDraft.json new file mode 100644 index 0000000000..0445a0fdbf --- /dev/null +++ b/lexicons/app/bsky/draft/deleteDraft.json @@ -0,0 +1,23 @@ +{ + "lexicon": 1, + "id": "app.bsky.draft.deleteDraft", + "defs": { + "main": { + "type": "procedure", + "description": "Deletes a draft by ID. Requires authentication.", + "input": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["id"], + "properties": { + "id": { + "type": "string", + "format": "tid" + } + } + } + } + } + } +} diff --git a/lexicons/app/bsky/draft/getDrafts.json b/lexicons/app/bsky/draft/getDrafts.json new file mode 100644 index 0000000000..feb286089f --- /dev/null +++ b/lexicons/app/bsky/draft/getDrafts.json @@ -0,0 +1,43 @@ +{ + "lexicon": 1, + "id": "app.bsky.draft.getDrafts", + "defs": { + "main": { + "type": "query", + "description": "Gets views of user drafts. Requires authentication.", + "parameters": { + "type": "params", + "properties": { + "limit": { + "type": "integer", + "minimum": 1, + "maximum": 100, + "default": 50 + }, + "cursor": { + "type": "string" + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["drafts"], + "properties": { + "cursor": { + "type": "string" + }, + "drafts": { + "type": "array", + "items": { + "type": "ref", + "ref": "app.bsky.draft.defs#draftView" + } + } + } + } + } + } + } +} diff --git a/lexicons/app/bsky/draft/updateDraft.json b/lexicons/app/bsky/draft/updateDraft.json new file mode 100644 index 0000000000..6b1b6fc74c --- /dev/null +++ b/lexicons/app/bsky/draft/updateDraft.json @@ -0,0 +1,23 @@ +{ + "lexicon": 1, + "id": "app.bsky.draft.updateDraft", + "defs": { + "main": { + "type": "procedure", + "description": "Updates a draft using private storage (stash). If the draft ID points to a non-existing ID, the update will be silently ignored. This is done because updates don't enforce draft limit, so it accepts all writes, but will ignore invalid ones. Requires authentication.", + "input": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["draft"], + "properties": { + "draft": { + "type": "ref", + "ref": "app.bsky.draft.defs#draftWithId" + } + } + } + } + } + } +} diff --git a/lexicons/app/bsky/embed/defs.json b/lexicons/app/bsky/embed/defs.json new file mode 100644 index 0000000000..63a5a8b083 --- /dev/null +++ b/lexicons/app/bsky/embed/defs.json @@ -0,0 +1,21 @@ +{ + "lexicon": 1, + "id": "app.bsky.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 + } + } + } + } +} diff --git a/lexicons/app/bsky/embed/external.json b/lexicons/app/bsky/embed/external.json new file mode 100644 index 0000000000..2fe2b18b03 --- /dev/null +++ b/lexicons/app/bsky/embed/external.json @@ -0,0 +1,188 @@ +{ + "lexicon": 1, + "id": "app.bsky.embed.external", + "defs": { + "main": { + "type": "object", + "description": "A representation of some externally linked content (eg, a URL and 'card'), embedded in a Bluesky record (eg, a post).", + "required": ["external"], + "properties": { + "external": { + "type": "ref", + "ref": "#external" + } + } + }, + "external": { + "type": "object", + "required": ["uri", "title", "description"], + "properties": { + "uri": { + "type": "string", + "format": "uri" + }, + "title": { + "type": "string" + }, + "description": { + "type": "string" + }, + "thumb": { + "type": "blob", + "accept": ["image/*"], + "maxSize": 1000000 + }, + "associatedRefs": { + "type": "array", + "items": { + "type": "ref", + "ref": "com.atproto.repo.strongRef" + }, + "description": "StrongRefs (uri+cid) of the Atmosphere records that backed this view." + } + } + }, + "view": { + "type": "object", + "required": ["external"], + "properties": { + "external": { + "type": "ref", + "ref": "#viewExternal" + } + } + }, + "viewExternal": { + "type": "object", + "required": ["uri", "title", "description"], + "properties": { + "uri": { + "type": "string", + "format": "uri" + }, + "title": { + "type": "string" + }, + "description": { + "type": "string" + }, + "thumb": { + "type": "string", + "format": "uri" + }, + "createdAt": { + "type": "string", + "format": "datetime", + "description": "When the external content was created, if available. Example: a publication date, for an article." + }, + "updatedAt": { + "type": "string", + "format": "datetime", + "description": "When the external content was updated, if available." + }, + "readingTime": { + "type": "integer", + "description": "Estimated reading time in minutes, if applicable and available." + }, + "labels": { + "type": "array", + "items": { + "type": "ref", + "ref": "com.atproto.label.defs#label" + } + }, + "source": { + "type": "ref", + "ref": "#viewExternalSource" + }, + "associatedRefs": { + "type": "array", + "items": { + "type": "ref", + "ref": "com.atproto.repo.strongRef" + }, + "description": "StrongRefs (uri+cid) of the Atmosphere records that backed this view." + }, + "associatedProfiles": { + "type": "array", + "items": { + "type": "ref", + "ref": "app.bsky.actor.defs#profileViewBasic" + }, + "description": "Profiles of the owners of the Atmosphere records that backed this view." + } + } + }, + "viewExternalSource": { + "type": "object", + "description": "The source of an external embed, such as a standard.site publication.", + "required": ["uri", "title"], + "properties": { + "uri": { + "type": "string", + "format": "uri", + "description": "URI of the source, if available. Example: the https:// URL of a site.standard.publication record." + }, + "icon": { + "type": "string", + "format": "uri", + "description": "Fully-qualified URL where an icon representing the source can be fetched. For example, CDN location provided by the App View." + }, + "title": { + "type": "string" + }, + "description": { + "type": "string" + }, + "theme": { + "type": "ref", + "ref": "#viewExternalSourceTheme" + } + } + }, + "viewExternalSourceTheme": { + "type": "object", + "description": "The theme colors of an external source, such as a site.standard.publication. These colors may be used when rendering an embed from that source.", + "properties": { + "backgroundRGB": { + "type": "ref", + "ref": "#colorRGB" + }, + "foregroundRGB": { + "type": "ref", + "ref": "#colorRGB" + }, + "accentRGB": { + "type": "ref", + "ref": "#colorRGB" + }, + "accentForegroundRGB": { + "type": "ref", + "ref": "#colorRGB" + } + } + }, + "colorRGB": { + "type": "object", + "description": "RGB color definition, inspired by site.standard.theme.color#rgb", + "required": ["r", "g", "b"], + "properties": { + "r": { + "type": "integer", + "minimum": 0, + "maximum": 255 + }, + "g": { + "type": "integer", + "minimum": 0, + "maximum": 255 + }, + "b": { + "type": "integer", + "minimum": 0, + "maximum": 255 + } + } + } + } +} diff --git a/lexicons/app/bsky/embed/gallery.json b/lexicons/app/bsky/embed/gallery.json new file mode 100644 index 0000000000..916093da8a --- /dev/null +++ b/lexicons/app/bsky/embed/gallery.json @@ -0,0 +1,79 @@ +{ + "lexicon": 1, + "id": "app.bsky.embed.gallery", + "description": "An assortment of media embedded in a Bluesky record (eg, a post).", + "defs": { + "main": { + "type": "object", + "required": ["items"], + "properties": { + "items": { + "type": "array", + "maxLength": 20, + "description": "The schema-level maxLength of 20 is a future-proof ceiling. Clients should currently enforce a soft limit of 10 items in authoring UIs.", + "items": { + "type": "union", + "refs": ["#image"], + "description": "The media items in the gallery. Each item may be of a different type, but all types must be supported by the client." + } + } + } + }, + "image": { + "type": "object", + "required": ["image", "alt", "aspectRatio"], + "properties": { + "image": { + "type": "blob", + "accept": ["image/*"], + "maxSize": 2000000 + }, + "alt": { + "type": "string", + "description": "Alt text description of the image, for accessibility." + }, + "aspectRatio": { + "type": "ref", + "ref": "app.bsky.embed.defs#aspectRatio" + } + } + }, + "view": { + "type": "object", + "required": ["items"], + "properties": { + "items": { + "type": "array", + "items": { + "type": "union", + "refs": ["#viewImage"] + } + } + } + }, + "viewImage": { + "type": "object", + "required": ["thumbnail", "fullsize", "alt", "aspectRatio"], + "properties": { + "thumbnail": { + "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": "app.bsky.embed.defs#aspectRatio" + } + } + } + } +} diff --git a/lexicons/app/bsky/embed/getEmbedExternalView.json b/lexicons/app/bsky/embed/getEmbedExternalView.json new file mode 100644 index 0000000000..382953ec36 --- /dev/null +++ b/lexicons/app/bsky/embed/getEmbedExternalView.json @@ -0,0 +1,58 @@ +{ + "lexicon": 1, + "id": "app.bsky.embed.getEmbedExternalView", + "defs": { + "main": { + "type": "query", + "description": "Resolve one or more AT-URIs into the data needed to render an enhanced external embed. Returns `associatedRefs` (strongRefs to embed into a post's external.associatedRefs), the raw `associatedRecords`, and a hydrated `view`. The response is empty (`{}`) when no records were resolvable, or when validation determined the resolved records don't actually back the requested URL; clients should fall back to their own link-card rendering in that case and skip writing strongRefs to the post.", + "parameters": { + "type": "params", + "required": ["url", "uris"], + "properties": { + "url": { + "type": "string", + "format": "uri", + "description": "The canonical web URL the embed represents (typically the URL the user pasted into the composer). Used as the returned view's `uri`. May be used for validation in the future." + }, + "uris": { + "type": "array", + "description": "AT-URIs of any Atmosphere records that can be resolved and used to construct #externalView views. Example: a site.standard.document and optionally its associated site.standard.publication.", + "items": { + "type": "string", + "format": "at-uri" + }, + "maxLength": 4 + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "properties": { + "view": { + "type": "ref", + "ref": "app.bsky.embed.external#view", + "description": "Hydrated view of the embed. Present only when the resolved records back the requested URL and supply enough information to populate the required `viewExternal` fields. Omitted alongside the rest of the response when no records resolved or validation failed." + }, + "associatedRefs": { + "type": "array", + "items": { + "type": "ref", + "ref": "com.atproto.repo.strongRef" + }, + "description": "StrongRefs (URI+CID) of the Atmosphere records that backed this view, suitable for embedding into a post's external.associatedRefs." + }, + "associatedRecords": { + "type": "array", + "items": { + "type": "unknown", + "description": "The raw record data of the Atmosphere records that backed this view. This is returned for convenience, to avoid the need for the client to separately fetch the record data for the associatedRefs. Example: the site.standard.document and site.standard.publication records that backed this view." + } + } + } + } + } + } + } +} diff --git a/lexicons/app/bsky/embed/images.json b/lexicons/app/bsky/embed/images.json new file mode 100644 index 0000000000..e11d4f0f81 --- /dev/null +++ b/lexicons/app/bsky/embed/images.json @@ -0,0 +1,79 @@ +{ + "lexicon": 1, + "id": "app.bsky.embed.images", + "description": "A set of images embedded in a Bluesky record (eg, a post).", + "defs": { + "main": { + "type": "object", + "required": ["images"], + "properties": { + "images": { + "type": "array", + "items": { + "type": "ref", + "ref": "#image" + }, + "maxLength": 4 + } + } + }, + "image": { + "type": "object", + "required": ["image", "alt"], + "properties": { + "image": { + "type": "blob", + "description": "The raw image file. May be up to 2 MB, formerly limited to 1 MB.", + "accept": ["image/*"], + "maxSize": 2000000 + }, + "alt": { + "type": "string", + "description": "Alt text description of the image, for accessibility." + }, + "aspectRatio": { + "type": "ref", + "ref": "app.bsky.embed.defs#aspectRatio" + } + } + }, + "view": { + "type": "object", + "required": ["images"], + "properties": { + "images": { + "type": "array", + "items": { + "type": "ref", + "ref": "#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": "app.bsky.embed.defs#aspectRatio" + } + } + } + } +} diff --git a/lexicons/app/bsky/embed/record.json b/lexicons/app/bsky/embed/record.json new file mode 100644 index 0000000000..51783ffacd --- /dev/null +++ b/lexicons/app/bsky/embed/record.json @@ -0,0 +1,141 @@ +{ + "lexicon": 1, + "id": "app.bsky.embed.record", + "description": "A representation of a record embedded in a Bluesky record (eg, a post). For example, a quote-post, or sharing a feed generator record.", + "defs": { + "main": { + "type": "object", + "required": ["record"], + "properties": { + "record": { + "type": "ref", + "ref": "com.atproto.repo.strongRef" + } + } + }, + "view": { + "type": "object", + "required": ["record"], + "properties": { + "record": { + "type": "union", + "refs": [ + "#viewRecord", + "#viewNotFound", + "#viewBlocked", + "#viewDetached", + "app.bsky.feed.defs#generatorView", + "app.bsky.graph.defs#listView", + "app.bsky.labeler.defs#labelerView", + "app.bsky.graph.defs#starterPackViewBasic" + ] + } + } + }, + "viewRecord": { + "type": "object", + "required": ["uri", "cid", "author", "value", "indexedAt"], + "properties": { + "uri": { + "type": "string", + "format": "at-uri" + }, + "cid": { + "type": "string", + "format": "cid" + }, + "author": { + "type": "ref", + "ref": "app.bsky.actor.defs#profileViewBasic" + }, + "value": { + "type": "unknown", + "description": "The record data itself." + }, + "labels": { + "type": "array", + "items": { + "type": "ref", + "ref": "com.atproto.label.defs#label" + } + }, + "replyCount": { + "type": "integer" + }, + "repostCount": { + "type": "integer" + }, + "likeCount": { + "type": "integer" + }, + "quoteCount": { + "type": "integer" + }, + "embeds": { + "type": "array", + "items": { + "type": "union", + "refs": [ + "app.bsky.embed.images#view", + "app.bsky.embed.video#view", + "app.bsky.embed.gallery#view", + "app.bsky.embed.external#view", + "app.bsky.embed.record#view", + "app.bsky.embed.recordWithMedia#view" + ] + } + }, + "indexedAt": { + "type": "string", + "format": "datetime" + } + } + }, + "viewNotFound": { + "type": "object", + "required": ["uri", "notFound"], + "properties": { + "uri": { + "type": "string", + "format": "at-uri" + }, + "notFound": { + "type": "boolean", + "const": true + } + } + }, + "viewBlocked": { + "type": "object", + "required": ["uri", "blocked", "author"], + "properties": { + "uri": { + "type": "string", + "format": "at-uri" + }, + "blocked": { + "type": "boolean", + "const": true + }, + "author": { + "type": "ref", + "ref": "app.bsky.feed.defs#blockedAuthor" + } + } + }, + "viewDetached": { + "type": "object", + "required": ["uri", "detached"], + "properties": { + "uri": { + "type": "string", + "format": "at-uri" + }, + "detached": { + "type": "boolean", + "const": true + } + } + } + } +} diff --git a/lexicons/app/bsky/embed/recordWithMedia.json b/lexicons/app/bsky/embed/recordWithMedia.json new file mode 100644 index 0000000000..edd765034a --- /dev/null +++ b/lexicons/app/bsky/embed/recordWithMedia.json @@ -0,0 +1,45 @@ +{ + "lexicon": 1, + "id": "app.bsky.embed.recordWithMedia", + "description": "A representation of a record embedded in a Bluesky record (eg, a post), alongside other compatible embeds. For example, a quote post and image, or a quote post and external URL card.", + "defs": { + "main": { + "type": "object", + "required": ["record", "media"], + "properties": { + "record": { + "type": "ref", + "ref": "app.bsky.embed.record" + }, + "media": { + "type": "union", + "refs": [ + "app.bsky.embed.images", + "app.bsky.embed.video", + "app.bsky.embed.gallery", + "app.bsky.embed.external" + ] + } + } + }, + "view": { + "type": "object", + "required": ["record", "media"], + "properties": { + "record": { + "type": "ref", + "ref": "app.bsky.embed.record#view" + }, + "media": { + "type": "union", + "refs": [ + "app.bsky.embed.images#view", + "app.bsky.embed.video#view", + "app.bsky.embed.gallery#view", + "app.bsky.embed.external#view" + ] + } + } + } + } +} diff --git a/lexicons/app/bsky/embed/video.json b/lexicons/app/bsky/embed/video.json new file mode 100644 index 0000000000..ff45914f25 --- /dev/null +++ b/lexicons/app/bsky/embed/video.json @@ -0,0 +1,89 @@ +{ + "lexicon": 1, + "id": "app.bsky.embed.video", + "description": "A video embedded in a Bluesky record (eg, a post).", + "defs": { + "main": { + "type": "object", + "required": ["video"], + "properties": { + "video": { + "type": "blob", + "description": "The mp4 video file. May be up to 100mb, formerly limited to 50mb.", + "accept": ["video/mp4"], + "maxSize": 100000000 + }, + "captions": { + "type": "array", + "items": { + "type": "ref", + "ref": "#caption" + }, + "maxLength": 20 + }, + "alt": { + "type": "string", + "description": "Alt text description of the video, for accessibility.", + "maxGraphemes": 1000, + "maxLength": 10000 + }, + "aspectRatio": { + "type": "ref", + "ref": "app.bsky.embed.defs#aspectRatio" + }, + "presentation": { + "type": "string", + "description": "A hint to the client about how to present the video.", + "knownValues": ["default", "gif"] + } + } + }, + "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": "app.bsky.embed.defs#aspectRatio" + }, + "presentation": { + "type": "string", + "description": "A hint to the client about how to present the video.", + "knownValues": ["default", "gif"] + } + } + } + } +} diff --git a/lexicons/app/bsky/feed/defs.json b/lexicons/app/bsky/feed/defs.json new file mode 100644 index 0000000000..c351d333fa --- /dev/null +++ b/lexicons/app/bsky/feed/defs.json @@ -0,0 +1,486 @@ +{ + "lexicon": 1, + "id": "app.bsky.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": "app.bsky.actor.defs#profileViewBasic" + }, + "record": { + "type": "unknown" + }, + "embed": { + "type": "union", + "refs": [ + "app.bsky.embed.images#view", + "app.bsky.embed.video#view", + "app.bsky.embed.gallery#view", + "app.bsky.embed.external#view", + "app.bsky.embed.record#view", + "app.bsky.embed.recordWithMedia#view" + ] + }, + "bookmarkCount": { + "type": "integer" + }, + "replyCount": { + "type": "integer" + }, + "repostCount": { + "type": "integer" + }, + "likeCount": { + "type": "integer" + }, + "quoteCount": { + "type": "integer" + }, + "indexedAt": { + "type": "string", + "format": "datetime" + }, + "viewer": { + "type": "ref", + "ref": "#viewerState" + }, + "labels": { + "type": "array", + "items": { + "type": "ref", + "ref": "com.atproto.label.defs#label" + } + }, + "threadgate": { + "type": "ref", + "ref": "#threadgateView" + }, + "debug": { + "type": "unknown", + "description": "Debug information for internal development" + } + } + }, + "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" + }, + "bookmarked": { + "type": "boolean" + }, + "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": "#postView" + }, + "reply": { + "type": "ref", + "ref": "#replyRef" + }, + "reason": { + "type": "union", + "refs": ["#reasonRepost", "#reasonPin"] + }, + "feedContext": { + "type": "string", + "description": "Context provided by feed generator that may be passed back alongside interactions.", + "maxLength": 2000 + }, + "reqId": { + "type": "string", + "description": "Unique identifier per request that may be passed back alongside interactions.", + "maxLength": 100 + } + } + }, + "replyRef": { + "type": "object", + "required": ["root", "parent"], + "properties": { + "root": { + "type": "union", + "refs": ["#postView", "#notFoundPost", "#blockedPost"] + }, + "parent": { + "type": "union", + "refs": ["#postView", "#notFoundPost", "#blockedPost"] + }, + "grandparentAuthor": { + "type": "ref", + "ref": "app.bsky.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": "app.bsky.actor.defs#profileViewBasic" + }, + "uri": { + "type": "string", + "format": "at-uri" + }, + "cid": { + "type": "string", + "format": "cid" + }, + "indexedAt": { + "type": "string", + "format": "datetime" + } + } + }, + "reasonPin": { + "type": "object", + "properties": {} + }, + "threadViewPost": { + "type": "object", + "required": ["post"], + "properties": { + "post": { + "type": "ref", + "ref": "#postView" + }, + "parent": { + "type": "union", + "refs": ["#threadViewPost", "#notFoundPost", "#blockedPost"] + }, + "replies": { + "type": "array", + "items": { + "type": "union", + "refs": ["#threadViewPost", "#notFoundPost", "#blockedPost"] + } + }, + "threadContext": { + "type": "ref", + "ref": "#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": "#blockedAuthor" + } + } + }, + "blockedAuthor": { + "type": "object", + "required": ["did"], + "properties": { + "did": { + "type": "string", + "format": "did" + }, + "viewer": { + "type": "ref", + "ref": "app.bsky.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": "app.bsky.actor.defs#profileView" + }, + "displayName": { + "type": "string" + }, + "description": { + "type": "string", + "maxGraphemes": 300, + "maxLength": 3000 + }, + "descriptionFacets": { + "type": "array", + "items": { + "type": "ref", + "ref": "app.bsky.richtext.facet" + } + }, + "avatar": { + "type": "string", + "format": "uri" + }, + "likeCount": { + "type": "integer", + "minimum": 0 + }, + "acceptsInteractions": { + "type": "boolean" + }, + "labels": { + "type": "array", + "items": { + "type": "ref", + "ref": "com.atproto.label.defs#label" + } + }, + "viewer": { + "type": "ref", + "ref": "#generatorViewerState" + }, + "contentMode": { + "type": "string", + "knownValues": [ + "app.bsky.feed.defs#contentModeUnspecified", + "app.bsky.feed.defs#contentModeVideo" + ] + }, + "indexedAt": { + "type": "string", + "format": "datetime" + } + } + }, + "generatorViewerState": { + "type": "object", + "properties": { + "like": { + "type": "string", + "format": "at-uri" + } + } + }, + "skeletonFeedPost": { + "type": "object", + "required": ["post"], + "properties": { + "post": { + "type": "string", + "format": "at-uri" + }, + "reason": { + "type": "union", + "refs": ["#skeletonReasonRepost", "#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": "app.bsky.graph.defs#listViewBasic" + } + } + } + }, + "interaction": { + "type": "object", + "properties": { + "item": { + "type": "string", + "format": "at-uri" + }, + "event": { + "type": "string", + "knownValues": [ + "app.bsky.feed.defs#requestLess", + "app.bsky.feed.defs#requestMore", + "app.bsky.feed.defs#clickthroughItem", + "app.bsky.feed.defs#clickthroughAuthor", + "app.bsky.feed.defs#clickthroughReposter", + "app.bsky.feed.defs#clickthroughEmbed", + "app.bsky.feed.defs#interactionSeen", + "app.bsky.feed.defs#interactionLike", + "app.bsky.feed.defs#interactionRepost", + "app.bsky.feed.defs#interactionReply", + "app.bsky.feed.defs#interactionQuote", + "app.bsky.feed.defs#interactionShare" + ] + }, + "feedContext": { + "type": "string", + "description": "Context on a feed item that was originally supplied by the feed generator on getFeedSkeleton.", + "maxLength": 2000 + }, + "reqId": { + "type": "string", + "description": "Unique identifier per request that may be passed back alongside interactions.", + "maxLength": 100 + } + } + }, + "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 app.bsky.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" + } + } +} diff --git a/lexicons/app/bsky/feed/describeFeedGenerator.json b/lexicons/app/bsky/feed/describeFeedGenerator.json new file mode 100644 index 0000000000..4d6db5d7e0 --- /dev/null +++ b/lexicons/app/bsky/feed/describeFeedGenerator.json @@ -0,0 +1,55 @@ +{ + "lexicon": 1, + "id": "app.bsky.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": "#feed" + } + }, + "links": { + "type": "ref", + "ref": "#links" + } + } + } + } + }, + "feed": { + "type": "object", + "required": ["uri"], + "properties": { + "uri": { + "type": "string", + "format": "at-uri" + } + } + }, + "links": { + "type": "object", + "properties": { + "privacyPolicy": { + "type": "string" + }, + "termsOfService": { + "type": "string" + } + } + } + } +} diff --git a/lexicons/app/bsky/feed/generator.json b/lexicons/app/bsky/feed/generator.json new file mode 100644 index 0000000000..00548a0567 --- /dev/null +++ b/lexicons/app/bsky/feed/generator.json @@ -0,0 +1,63 @@ +{ + "lexicon": 1, + "id": "app.bsky.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": "app.bsky.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 app.bsky.feed.sendInteractions" + }, + "labels": { + "type": "union", + "description": "Self-label values", + "refs": ["com.atproto.label.defs#selfLabels"] + }, + "contentMode": { + "type": "string", + "knownValues": [ + "app.bsky.feed.defs#contentModeUnspecified", + "app.bsky.feed.defs#contentModeVideo" + ] + }, + "createdAt": { + "type": "string", + "format": "datetime" + } + } + } + } + } +} diff --git a/lexicons/app/bsky/feed/getActorFeeds.json b/lexicons/app/bsky/feed/getActorFeeds.json new file mode 100644 index 0000000000..44b45ee47f --- /dev/null +++ b/lexicons/app/bsky/feed/getActorFeeds.json @@ -0,0 +1,48 @@ +{ + "lexicon": 1, + "id": "app.bsky.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": "app.bsky.feed.defs#generatorView" + } + } + } + } + } + } + } +} diff --git a/lexicons/app/bsky/feed/getActorLikes.json b/lexicons/app/bsky/feed/getActorLikes.json new file mode 100644 index 0000000000..e70dc30cff --- /dev/null +++ b/lexicons/app/bsky/feed/getActorLikes.json @@ -0,0 +1,56 @@ +{ + "lexicon": 1, + "id": "app.bsky.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": "app.bsky.feed.defs#feedViewPost" + } + } + } + } + }, + "errors": [ + { + "name": "BlockedActor" + }, + { + "name": "BlockedByActor" + } + ] + } + } +} diff --git a/lexicons/app/bsky/feed/getAuthorFeed.json b/lexicons/app/bsky/feed/getAuthorFeed.json new file mode 100644 index 0000000000..635937b076 --- /dev/null +++ b/lexicons/app/bsky/feed/getAuthorFeed.json @@ -0,0 +1,72 @@ +{ + "lexicon": 1, + "id": "app.bsky.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": "app.bsky.feed.defs#feedViewPost" + } + } + } + } + }, + "errors": [ + { + "name": "BlockedActor" + }, + { + "name": "BlockedByActor" + } + ] + } + } +} diff --git a/lexicons/app/bsky/feed/getFeed.json b/lexicons/app/bsky/feed/getFeed.json new file mode 100644 index 0000000000..5d20f5cfce --- /dev/null +++ b/lexicons/app/bsky/feed/getFeed.json @@ -0,0 +1,53 @@ +{ + "lexicon": 1, + "id": "app.bsky.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": "app.bsky.feed.defs#feedViewPost" + } + } + } + } + }, + "errors": [ + { + "name": "UnknownFeed" + } + ] + } + } +} diff --git a/lexicons/app/bsky/feed/getFeedGenerator.json b/lexicons/app/bsky/feed/getFeedGenerator.json new file mode 100644 index 0000000000..190eca85b2 --- /dev/null +++ b/lexicons/app/bsky/feed/getFeedGenerator.json @@ -0,0 +1,42 @@ +{ + "lexicon": 1, + "id": "app.bsky.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": "app.bsky.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." + } + } + } + } + } + } +} diff --git a/lexicons/app/bsky/feed/getFeedGenerators.json b/lexicons/app/bsky/feed/getFeedGenerators.json new file mode 100644 index 0000000000..5dbbe5631e --- /dev/null +++ b/lexicons/app/bsky/feed/getFeedGenerators.json @@ -0,0 +1,39 @@ +{ + "lexicon": 1, + "id": "app.bsky.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": "app.bsky.feed.defs#generatorView" + } + } + } + } + } + } + } +} diff --git a/lexicons/app/bsky/feed/getFeedSkeleton.json b/lexicons/app/bsky/feed/getFeedSkeleton.json new file mode 100644 index 0000000000..f625003caa --- /dev/null +++ b/lexicons/app/bsky/feed/getFeedSkeleton.json @@ -0,0 +1,59 @@ +{ + "lexicon": 1, + "id": "app.bsky.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": "app.bsky.feed.defs#skeletonFeedPost" + } + }, + "reqId": { + "type": "string", + "description": "Unique identifier per request that may be passed back alongside interactions.", + "maxLength": 100 + } + } + } + }, + "errors": [ + { + "name": "UnknownFeed" + } + ] + } + } +} diff --git a/lexicons/app/bsky/feed/getLikes.json b/lexicons/app/bsky/feed/getLikes.json new file mode 100644 index 0000000000..d916f7932a --- /dev/null +++ b/lexicons/app/bsky/feed/getLikes.json @@ -0,0 +1,80 @@ +{ + "lexicon": 1, + "id": "app.bsky.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": "#like" + } + } + } + } + } + }, + "like": { + "type": "object", + "required": ["indexedAt", "createdAt", "actor"], + "properties": { + "indexedAt": { + "type": "string", + "format": "datetime" + }, + "createdAt": { + "type": "string", + "format": "datetime" + }, + "actor": { + "type": "ref", + "ref": "app.bsky.actor.defs#profileView" + } + } + } + } +} diff --git a/lexicons/app/bsky/feed/getListFeed.json b/lexicons/app/bsky/feed/getListFeed.json new file mode 100644 index 0000000000..4555c5011c --- /dev/null +++ b/lexicons/app/bsky/feed/getListFeed.json @@ -0,0 +1,54 @@ +{ + "lexicon": 1, + "id": "app.bsky.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": "app.bsky.feed.defs#feedViewPost" + } + } + } + } + }, + "errors": [ + { + "name": "UnknownList" + } + ] + } + } +} diff --git a/lexicons/app/bsky/feed/getPostThread.json b/lexicons/app/bsky/feed/getPostThread.json new file mode 100644 index 0000000000..ed29d4d8c9 --- /dev/null +++ b/lexicons/app/bsky/feed/getPostThread.json @@ -0,0 +1,61 @@ +{ + "lexicon": 1, + "id": "app.bsky.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": [ + "app.bsky.feed.defs#threadViewPost", + "app.bsky.feed.defs#notFoundPost", + "app.bsky.feed.defs#blockedPost" + ] + }, + "threadgate": { + "type": "ref", + "ref": "app.bsky.feed.defs#threadgateView" + } + } + } + }, + "errors": [ + { + "name": "NotFound" + } + ] + } + } +} diff --git a/lexicons/app/bsky/feed/getPosts.json b/lexicons/app/bsky/feed/getPosts.json new file mode 100644 index 0000000000..96e24f39e8 --- /dev/null +++ b/lexicons/app/bsky/feed/getPosts.json @@ -0,0 +1,41 @@ +{ + "lexicon": 1, + "id": "app.bsky.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": "app.bsky.feed.defs#postView" + } + } + } + } + } + } + } +} diff --git a/lexicons/app/bsky/feed/getQuotes.json b/lexicons/app/bsky/feed/getQuotes.json new file mode 100644 index 0000000000..09b870f9af --- /dev/null +++ b/lexicons/app/bsky/feed/getQuotes.json @@ -0,0 +1,62 @@ +{ + "lexicon": 1, + "id": "app.bsky.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": "app.bsky.feed.defs#postView" + } + } + } + } + } + } + } +} diff --git a/lexicons/app/bsky/feed/getRepostedBy.json b/lexicons/app/bsky/feed/getRepostedBy.json new file mode 100644 index 0000000000..0e0fea71ea --- /dev/null +++ b/lexicons/app/bsky/feed/getRepostedBy.json @@ -0,0 +1,62 @@ +{ + "lexicon": 1, + "id": "app.bsky.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": "app.bsky.actor.defs#profileView" + } + } + } + } + } + } + } +} diff --git a/lexicons/app/bsky/feed/getSuggestedFeeds.json b/lexicons/app/bsky/feed/getSuggestedFeeds.json new file mode 100644 index 0000000000..a677a6920e --- /dev/null +++ b/lexicons/app/bsky/feed/getSuggestedFeeds.json @@ -0,0 +1,43 @@ +{ + "lexicon": 1, + "id": "app.bsky.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": "app.bsky.feed.defs#generatorView" + } + } + } + } + } + } + } +} diff --git a/lexicons/app/bsky/feed/getTimeline.json b/lexicons/app/bsky/feed/getTimeline.json new file mode 100644 index 0000000000..c7ea63f460 --- /dev/null +++ b/lexicons/app/bsky/feed/getTimeline.json @@ -0,0 +1,47 @@ +{ + "lexicon": 1, + "id": "app.bsky.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": "app.bsky.feed.defs#feedViewPost" + } + } + } + } + } + } + } +} diff --git a/lexicons/app/bsky/feed/like.json b/lexicons/app/bsky/feed/like.json new file mode 100644 index 0000000000..8385e705d9 --- /dev/null +++ b/lexicons/app/bsky/feed/like.json @@ -0,0 +1,29 @@ +{ + "lexicon": 1, + "id": "app.bsky.feed.like", + "defs": { + "main": { + "type": "record", + "description": "Record declaring a 'like' of a piece of subject content.", + "key": "tid", + "record": { + "type": "object", + "required": ["subject", "createdAt"], + "properties": { + "subject": { + "type": "ref", + "ref": "com.atproto.repo.strongRef" + }, + "createdAt": { + "type": "string", + "format": "datetime" + }, + "via": { + "type": "ref", + "ref": "com.atproto.repo.strongRef" + } + } + } + } + } +} diff --git a/lexicons/app/bsky/feed/post.json b/lexicons/app/bsky/feed/post.json new file mode 100644 index 0000000000..c46bb8b3f4 --- /dev/null +++ b/lexicons/app/bsky/feed/post.json @@ -0,0 +1,130 @@ +{ + "lexicon": 1, + "id": "app.bsky.feed.post", + "defs": { + "main": { + "type": "record", + "description": "Record containing a Bluesky post.", + "key": "tid", + "record": { + "type": "object", + "required": ["text", "createdAt"], + "properties": { + "text": { + "type": "string", + "maxLength": 3000, + "maxGraphemes": 300, + "description": "The primary post content. May be an empty string, if there are embeds." + }, + "entities": { + "type": "array", + "description": "DEPRECATED: replaced by app.bsky.richtext.facet.", + "items": { + "type": "ref", + "ref": "#entity" + } + }, + "facets": { + "type": "array", + "description": "Annotations of text (mentions, URLs, hashtags, etc)", + "items": { + "type": "ref", + "ref": "app.bsky.richtext.facet" + } + }, + "reply": { + "type": "ref", + "ref": "#replyRef" + }, + "embed": { + "type": "union", + "refs": [ + "app.bsky.embed.images", + "app.bsky.embed.video", + "app.bsky.embed.gallery", + "app.bsky.embed.external", + "app.bsky.embed.record", + "app.bsky.embed.recordWithMedia" + ] + }, + "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": ["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": "com.atproto.repo.strongRef" + }, + "parent": { + "type": "ref", + "ref": "com.atproto.repo.strongRef" + } + } + }, + "entity": { + "type": "object", + "description": "Deprecated: use facets instead.", + "required": ["index", "type", "value"], + "properties": { + "index": { + "type": "ref", + "ref": "#textSlice" + }, + "type": { + "type": "string", + "description": "Expected values are 'mention' and 'link'." + }, + "value": { + "type": "string" + } + } + }, + "textSlice": { + "type": "object", + "description": "Deprecated. Use app.bsky.richtext instead -- A text segment. Start is inclusive, end is exclusive. Indices are for utf16-encoded strings.", + "required": ["start", "end"], + "properties": { + "start": { + "type": "integer", + "minimum": 0 + }, + "end": { + "type": "integer", + "minimum": 0 + } + } + } + } +} diff --git a/lexicons/app/bsky/feed/postgate.json b/lexicons/app/bsky/feed/postgate.json new file mode 100644 index 0000000000..f3a9b35289 --- /dev/null +++ b/lexicons/app/bsky/feed/postgate.json @@ -0,0 +1,49 @@ +{ + "lexicon": 1, + "id": "app.bsky.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": ["#disableRule"] + } + } + } + } + }, + "disableRule": { + "type": "object", + "description": "Disables embedding of this post.", + "properties": {} + } + } +} diff --git a/lexicons/app/bsky/feed/repost.json b/lexicons/app/bsky/feed/repost.json new file mode 100644 index 0000000000..312c8ec072 --- /dev/null +++ b/lexicons/app/bsky/feed/repost.json @@ -0,0 +1,29 @@ +{ + "lexicon": 1, + "id": "app.bsky.feed.repost", + "defs": { + "main": { + "description": "Record representing a 'repost' of an existing Bluesky post.", + "type": "record", + "key": "tid", + "record": { + "type": "object", + "required": ["subject", "createdAt"], + "properties": { + "subject": { + "type": "ref", + "ref": "com.atproto.repo.strongRef" + }, + "createdAt": { + "type": "string", + "format": "datetime" + }, + "via": { + "type": "ref", + "ref": "com.atproto.repo.strongRef" + } + } + } + } + } +} diff --git a/lexicons/app/bsky/feed/searchPosts.json b/lexicons/app/bsky/feed/searchPosts.json new file mode 100644 index 0000000000..4a7a61db51 --- /dev/null +++ b/lexicons/app/bsky/feed/searchPosts.json @@ -0,0 +1,105 @@ +{ + "lexicon": 1, + "id": "app.bsky.feed.searchPosts", + "defs": { + "main": { + "type": "query", + "description": "Find posts matching search criteria, returning views of those posts. Note that this API endpoint may require authentication (eg, not public) for some service providers and implementations.", + "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": "app.bsky.feed.defs#postView" + } + } + } + } + }, + "errors": [ + { + "name": "BadQueryString" + } + ] + } + } +} diff --git a/lexicons/app/bsky/feed/searchPostsV2.json b/lexicons/app/bsky/feed/searchPostsV2.json new file mode 100644 index 0000000000..a412785bf3 --- /dev/null +++ b/lexicons/app/bsky/feed/searchPostsV2.json @@ -0,0 +1,233 @@ +{ + "lexicon": 1, + "id": "app.bsky.feed.searchPostsV2", + "defs": { + "main": { + "type": "query", + "description": "Find posts matching a search query or filters, returning search hits for matching post records.", + "parameters": { + "type": "params", + "required": [], + "properties": { + "cursor": { + "type": "string", + "description": "Optional pagination cursor." + }, + "limit": { + "type": "integer", + "minimum": 1, + "maximum": 100, + "default": 25, + "description": "Maximum number of results to return." + }, + "query": { + "type": "string", + "description": "Search query string. A query or at least one filter is required." + }, + "sort": { + "type": "string", + "knownValues": ["recent", "top"], + "description": "Ranking order for results. 'recent' sorts by recency; 'top' uses search ranking." + }, + "authors": { + "type": "array", + "items": { + "type": "string", + "format": "at-identifier" + }, + "description": "Include posts by any of these authors. Handles are resolved to DIDs before searching." + }, + "mentions": { + "type": "array", + "items": { + "type": "string", + "format": "at-identifier" + }, + "description": "Include posts that mention any of these accounts. Handles are resolved to DIDs before searching." + }, + "domains": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Include posts that link to any of these domains." + }, + "urls": { + "type": "array", + "items": { + "type": "string", + "format": "uri" + }, + "description": "Include posts that link to any of these URLs." + }, + "embeddedAtUris": { + "type": "array", + "items": { + "type": "string", + "format": "at-uri" + }, + "description": "Include posts that embed any of these AT URIs." + }, + "hashtags": { + "type": "array", + "items": { + "type": "string", + "maxLength": 640, + "maxGraphemes": 64 + }, + "description": "Include posts tagged with any of these hashtags. Do not include the hash (#) prefix." + }, + "excludeAuthors": { + "type": "array", + "items": { + "type": "string", + "format": "at-identifier" + }, + "description": "Exclude posts by any of these authors. Handles are resolved to DIDs before searching." + }, + "excludeMentions": { + "type": "array", + "items": { + "type": "string", + "format": "at-identifier" + }, + "description": "Exclude posts that mention any of these accounts. Handles are resolved to DIDs before searching." + }, + "excludeDomains": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Exclude posts that link to any of these domains." + }, + "excludeUrls": { + "type": "array", + "items": { + "type": "string", + "format": "uri" + }, + "description": "Exclude posts that link to any of these URLs." + }, + "excludeEmbeddedAtUris": { + "type": "array", + "items": { + "type": "string", + "format": "at-uri" + }, + "description": "Exclude posts that embed any of these AT URIs." + }, + "excludeHashtags": { + "type": "array", + "items": { + "type": "string", + "maxLength": 640, + "maxGraphemes": 64 + }, + "description": "Exclude posts tagged with any of these hashtags. Do not include the hash (#) prefix." + }, + "since": { + "type": "string", + "description": "Include posts indexed at or after this timestamp. Can be a datetime, or just an ISO date (YYYY-MM-DD)." + }, + "until": { + "type": "string", + "description": "Include posts indexed before this timestamp. Defaults to the current time. Can be a datetime, or just an ISO date (YYYY-MM-DD)." + }, + "allTime": { + "type": "boolean", + "description": "Search the full index instead of the recent-post window." + }, + "languages": { + "type": "array", + "items": { + "type": "string", + "format": "language" + }, + "description": "Include posts whose language matches any of these language codes." + }, + "excludeLanguages": { + "type": "array", + "items": { + "type": "string", + "format": "language" + }, + "description": "Exclude posts whose language matches any of these language codes." + }, + "hasMedia": { + "type": "boolean", + "description": "Include only posts with media." + }, + "hasVideo": { + "type": "boolean", + "description": "Include only posts with video." + }, + "replyParentUri": { + "type": "string", + "format": "at-uri", + "description": "Include only direct replies to this parent post URI." + }, + "threadRootUri": { + "type": "string", + "format": "at-uri", + "description": "Include only posts in the thread rooted at this post URI." + }, + "excludeReplies": { + "type": "boolean", + "description": "Exclude replies from results. Mutually exclusive with repliesOnly." + }, + "repliesOnly": { + "type": "boolean", + "description": "Include only replies. Mutually exclusive with excludeReplies." + }, + "following": { + "type": "boolean", + "description": "Include only posts from accounts followed by the viewer." + }, + "queryLanguage": { + "type": "string", + "knownValues": ["ja", "zh", "ko", "th", "ar"], + "description": "Language analyzer hint for the query text. If unset, the server auto-detects when possible." + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["posts"], + "properties": { + "cursor": { + "type": "string", + "description": "Cursor for the next page of results." + }, + "hitsTotal": { + "type": "integer", + "description": "Estimated total number of matching hits. May be rounded or truncated." + }, + "posts": { + "type": "array", + "items": { + "type": "ref", + "ref": "app.bsky.feed.defs#postView" + }, + "description": "Hydrated views of matching posts." + }, + "detectedQueryLanguages": { + "type": "array", + "items": { + "type": "string", + "knownValues": ["ja", "zh", "ko", "th", "ar"] + }, + "description": "Query languages detected for CJK, Thai, or Arabic text. Empty or omitted for other scripts." + } + } + } + }, + "errors": [ + { + "name": "BadQueryString" + } + ] + } + } +} diff --git a/lexicons/app/bsky/feed/sendInteractions.json b/lexicons/app/bsky/feed/sendInteractions.json new file mode 100644 index 0000000000..29cde02172 --- /dev/null +++ b/lexicons/app/bsky/feed/sendInteractions.json @@ -0,0 +1,37 @@ +{ + "lexicon": 1, + "id": "app.bsky.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": { + "feed": { + "type": "string", + "format": "at-uri" + }, + "interactions": { + "type": "array", + "items": { + "type": "ref", + "ref": "app.bsky.feed.defs#interaction" + } + } + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "properties": {} + } + } + } + } +} diff --git a/lexicons/app/bsky/feed/threadgate.json b/lexicons/app/bsky/feed/threadgate.json new file mode 100644 index 0000000000..9a71e7a92a --- /dev/null +++ b/lexicons/app/bsky/feed/threadgate.json @@ -0,0 +1,75 @@ +{ + "lexicon": 1, + "id": "app.bsky.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": [ + "#mentionRule", + "#followerRule", + "#followingRule", + "#listRule" + ] + } + }, + "createdAt": { + "type": "string", + "format": "datetime" + }, + "hiddenReplies": { + "type": "array", + "maxLength": 300, + "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" + } + } + } + } +} diff --git a/lexicons/app/bsky/graph/block.json b/lexicons/app/bsky/graph/block.json new file mode 100644 index 0000000000..9de036294c --- /dev/null +++ b/lexicons/app/bsky/graph/block.json @@ -0,0 +1,26 @@ +{ + "lexicon": 1, + "id": "app.bsky.graph.block", + "defs": { + "main": { + "type": "record", + "description": "Record declaring a 'block' relationship against another account. NOTE: blocks are public in Bluesky; 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" + } + } + } + } + } +} diff --git a/lexicons/app/bsky/graph/defs.json b/lexicons/app/bsky/graph/defs.json new file mode 100644 index 0000000000..123cce7f34 --- /dev/null +++ b/lexicons/app/bsky/graph/defs.json @@ -0,0 +1,320 @@ +{ + "lexicon": 1, + "id": "app.bsky.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": "#listPurpose" + }, + "avatar": { + "type": "string", + "format": "uri" + }, + "listItemCount": { + "type": "integer", + "minimum": 0 + }, + "labels": { + "type": "array", + "items": { + "type": "ref", + "ref": "com.atproto.label.defs#label" + } + }, + "viewer": { + "type": "ref", + "ref": "#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": "app.bsky.actor.defs#profileView" + }, + "name": { + "type": "string", + "maxLength": 64, + "minLength": 1 + }, + "purpose": { + "type": "ref", + "ref": "#listPurpose" + }, + "description": { + "type": "string", + "maxGraphemes": 300, + "maxLength": 3000 + }, + "descriptionFacets": { + "type": "array", + "items": { + "type": "ref", + "ref": "app.bsky.richtext.facet" + } + }, + "avatar": { + "type": "string", + "format": "uri" + }, + "listItemCount": { + "type": "integer", + "minimum": 0 + }, + "labels": { + "type": "array", + "items": { + "type": "ref", + "ref": "com.atproto.label.defs#label" + } + }, + "viewer": { + "type": "ref", + "ref": "#listViewerState" + }, + "indexedAt": { + "type": "string", + "format": "datetime" + } + } + }, + "listItemView": { + "type": "object", + "required": ["uri", "subject"], + "properties": { + "uri": { + "type": "string", + "format": "at-uri" + }, + "subject": { + "type": "ref", + "ref": "app.bsky.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": "app.bsky.actor.defs#profileViewBasic" + }, + "list": { + "type": "ref", + "ref": "#listViewBasic" + }, + "listItemsSample": { + "type": "array", + "maxLength": 12, + "items": { + "type": "ref", + "ref": "#listItemView" + } + }, + "feeds": { + "type": "array", + "maxLength": 3, + "items": { + "type": "ref", + "ref": "app.bsky.feed.defs#generatorView" + } + }, + "joinedWeekCount": { + "type": "integer", + "minimum": 0 + }, + "joinedAllTimeCount": { + "type": "integer", + "minimum": 0 + }, + "labels": { + "type": "array", + "items": { + "type": "ref", + "ref": "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": "app.bsky.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": "com.atproto.label.defs#label" + } + }, + "indexedAt": { + "type": "string", + "format": "datetime" + } + } + }, + "listPurpose": { + "type": "string", + "knownValues": [ + "app.bsky.graph.defs#modlist", + "app.bsky.graph.defs#curatelist", + "app.bsky.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" + }, + "blocking": { + "type": "string", + "format": "at-uri", + "description": "if the actor blocks this DID, this is the AT-URI of the block record" + }, + "blockedBy": { + "type": "string", + "format": "at-uri", + "description": "if the actor is blocked by this DID, contains the AT-URI of the block record" + }, + "blockingByList": { + "type": "string", + "format": "at-uri", + "description": "if the actor blocks this DID via a block list, this is the AT-URI of the listblock record" + }, + "blockedByList": { + "type": "string", + "format": "at-uri", + "description": "if the actor is blocked by this DID via a block list, contains the AT-URI of the listblock record" + } + } + } + } +} diff --git a/lexicons/app/bsky/graph/follow.json b/lexicons/app/bsky/graph/follow.json new file mode 100644 index 0000000000..b15f6c0875 --- /dev/null +++ b/lexicons/app/bsky/graph/follow.json @@ -0,0 +1,29 @@ +{ + "lexicon": 1, + "id": "app.bsky.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" + }, + "via": { + "type": "ref", + "ref": "com.atproto.repo.strongRef" + } + } + } + } + } +} diff --git a/lexicons/app/bsky/graph/getActorStarterPacks.json b/lexicons/app/bsky/graph/getActorStarterPacks.json new file mode 100644 index 0000000000..fb2ee152a0 --- /dev/null +++ b/lexicons/app/bsky/graph/getActorStarterPacks.json @@ -0,0 +1,48 @@ +{ + "lexicon": 1, + "id": "app.bsky.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": "app.bsky.graph.defs#starterPackViewBasic" + } + } + } + } + } + } + } +} diff --git a/lexicons/app/bsky/graph/getBlocks.json b/lexicons/app/bsky/graph/getBlocks.json new file mode 100644 index 0000000000..6856da840e --- /dev/null +++ b/lexicons/app/bsky/graph/getBlocks.json @@ -0,0 +1,43 @@ +{ + "lexicon": 1, + "id": "app.bsky.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": "app.bsky.actor.defs#profileView" + } + } + } + } + } + } + } +} diff --git a/lexicons/app/bsky/graph/getFollowers.json b/lexicons/app/bsky/graph/getFollowers.json new file mode 100644 index 0000000000..d91da22cac --- /dev/null +++ b/lexicons/app/bsky/graph/getFollowers.json @@ -0,0 +1,52 @@ +{ + "lexicon": 1, + "id": "app.bsky.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": "app.bsky.actor.defs#profileView" + }, + "cursor": { + "type": "string" + }, + "followers": { + "type": "array", + "items": { + "type": "ref", + "ref": "app.bsky.actor.defs#profileView" + } + } + } + } + } + } + } +} diff --git a/lexicons/app/bsky/graph/getFollows.json b/lexicons/app/bsky/graph/getFollows.json new file mode 100644 index 0000000000..2b1c0bad72 --- /dev/null +++ b/lexicons/app/bsky/graph/getFollows.json @@ -0,0 +1,52 @@ +{ + "lexicon": 1, + "id": "app.bsky.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": "app.bsky.actor.defs#profileView" + }, + "cursor": { + "type": "string" + }, + "follows": { + "type": "array", + "items": { + "type": "ref", + "ref": "app.bsky.actor.defs#profileView" + } + } + } + } + } + } + } +} diff --git a/lexicons/app/bsky/graph/getKnownFollowers.json b/lexicons/app/bsky/graph/getKnownFollowers.json new file mode 100644 index 0000000000..072539c66c --- /dev/null +++ b/lexicons/app/bsky/graph/getKnownFollowers.json @@ -0,0 +1,52 @@ +{ + "lexicon": 1, + "id": "app.bsky.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": "app.bsky.actor.defs#profileView" + }, + "cursor": { + "type": "string" + }, + "followers": { + "type": "array", + "items": { + "type": "ref", + "ref": "app.bsky.actor.defs#profileView" + } + } + } + } + } + } + } +} diff --git a/lexicons/app/bsky/graph/getList.json b/lexicons/app/bsky/graph/getList.json new file mode 100644 index 0000000000..97ac5434ba --- /dev/null +++ b/lexicons/app/bsky/graph/getList.json @@ -0,0 +1,53 @@ +{ + "lexicon": 1, + "id": "app.bsky.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": "app.bsky.graph.defs#listView" + }, + "items": { + "type": "array", + "items": { + "type": "ref", + "ref": "app.bsky.graph.defs#listItemView" + } + } + } + } + } + } + } +} diff --git a/lexicons/app/bsky/graph/getListBlocks.json b/lexicons/app/bsky/graph/getListBlocks.json new file mode 100644 index 0000000000..d21f45a63d --- /dev/null +++ b/lexicons/app/bsky/graph/getListBlocks.json @@ -0,0 +1,43 @@ +{ + "lexicon": 1, + "id": "app.bsky.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": "app.bsky.graph.defs#listView" + } + } + } + } + } + } + } +} diff --git a/lexicons/app/bsky/graph/getListMutes.json b/lexicons/app/bsky/graph/getListMutes.json new file mode 100644 index 0000000000..f30287d2cd --- /dev/null +++ b/lexicons/app/bsky/graph/getListMutes.json @@ -0,0 +1,43 @@ +{ + "lexicon": 1, + "id": "app.bsky.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": "app.bsky.graph.defs#listView" + } + } + } + } + } + } + } +} diff --git a/lexicons/app/bsky/graph/getLists.json b/lexicons/app/bsky/graph/getLists.json new file mode 100644 index 0000000000..9671d860c2 --- /dev/null +++ b/lexicons/app/bsky/graph/getLists.json @@ -0,0 +1,57 @@ +{ + "lexicon": 1, + "id": "app.bsky.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" + }, + "purposes": { + "type": "array", + "description": "Optional filter by list purpose. If not specified, all supported types are returned.", + "items": { + "type": "string", + "knownValues": ["modlist", "curatelist"] + } + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["lists"], + "properties": { + "cursor": { + "type": "string" + }, + "lists": { + "type": "array", + "items": { + "type": "ref", + "ref": "app.bsky.graph.defs#listView" + } + } + } + } + } + } + } +} diff --git a/lexicons/app/bsky/graph/getListsWithMembership.json b/lexicons/app/bsky/graph/getListsWithMembership.json new file mode 100644 index 0000000000..ac11fd9e7a --- /dev/null +++ b/lexicons/app/bsky/graph/getListsWithMembership.json @@ -0,0 +1,72 @@ +{ + "lexicon": 1, + "id": "app.bsky.graph.getListsWithMembership", + "defs": { + "main": { + "type": "query", + "description": "Enumerates the lists created by the session user, and includes membership information about `actor` in those lists. Only supports curation and moderation lists (no reference lists, used in starter packs). Requires auth.", + "parameters": { + "type": "params", + "required": ["actor"], + "properties": { + "actor": { + "type": "string", + "format": "at-identifier", + "description": "The account (actor) to check for membership." + }, + "limit": { + "type": "integer", + "minimum": 1, + "maximum": 100, + "default": 50 + }, + "cursor": { + "type": "string" + }, + "purposes": { + "type": "array", + "description": "Optional filter by list purpose. If not specified, all supported types are returned.", + "items": { + "type": "string", + "knownValues": ["modlist", "curatelist"] + } + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["listsWithMembership"], + "properties": { + "cursor": { + "type": "string" + }, + "listsWithMembership": { + "type": "array", + "items": { + "type": "ref", + "ref": "#listWithMembership" + } + } + } + } + } + }, + "listWithMembership": { + "description": "A list and an optional list item indicating membership of a target user to that list.", + "type": "object", + "required": ["list"], + "properties": { + "list": { + "type": "ref", + "ref": "app.bsky.graph.defs#listView" + }, + "listItem": { + "type": "ref", + "ref": "app.bsky.graph.defs#listItemView" + } + } + } + } +} diff --git a/lexicons/app/bsky/graph/getMutes.json b/lexicons/app/bsky/graph/getMutes.json new file mode 100644 index 0000000000..8c331dcba6 --- /dev/null +++ b/lexicons/app/bsky/graph/getMutes.json @@ -0,0 +1,43 @@ +{ + "lexicon": 1, + "id": "app.bsky.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": "app.bsky.actor.defs#profileView" + } + } + } + } + } + } + } +} diff --git a/lexicons/app/bsky/graph/getRelationships.json b/lexicons/app/bsky/graph/getRelationships.json new file mode 100644 index 0000000000..41eee47a47 --- /dev/null +++ b/lexicons/app/bsky/graph/getRelationships.json @@ -0,0 +1,59 @@ +{ + "lexicon": 1, + "id": "app.bsky.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": [ + "app.bsky.graph.defs#relationship", + "app.bsky.graph.defs#notFoundActor" + ] + } + } + } + } + }, + "errors": [ + { + "name": "ActorNotFound", + "description": "the primary actor at-identifier could not be resolved" + } + ] + } + } +} diff --git a/lexicons/app/bsky/graph/getStarterPack.json b/lexicons/app/bsky/graph/getStarterPack.json new file mode 100644 index 0000000000..b4ded4c711 --- /dev/null +++ b/lexicons/app/bsky/graph/getStarterPack.json @@ -0,0 +1,34 @@ +{ + "lexicon": 1, + "id": "app.bsky.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": "app.bsky.graph.defs#starterPackView" + } + } + } + } + } + } +} diff --git a/lexicons/app/bsky/graph/getStarterPacks.json b/lexicons/app/bsky/graph/getStarterPacks.json new file mode 100644 index 0000000000..2aa010710d --- /dev/null +++ b/lexicons/app/bsky/graph/getStarterPacks.json @@ -0,0 +1,40 @@ +{ + "lexicon": 1, + "id": "app.bsky.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": "app.bsky.graph.defs#starterPackViewBasic" + } + } + } + } + } + } + } +} diff --git a/lexicons/app/bsky/graph/getStarterPacksWithMembership.json b/lexicons/app/bsky/graph/getStarterPacksWithMembership.json new file mode 100644 index 0000000000..e5a962a6b1 --- /dev/null +++ b/lexicons/app/bsky/graph/getStarterPacksWithMembership.json @@ -0,0 +1,64 @@ +{ + "lexicon": 1, + "id": "app.bsky.graph.getStarterPacksWithMembership", + "defs": { + "main": { + "type": "query", + "description": "Enumerates the starter packs created by the session user, and includes membership information about `actor` in those starter packs. Requires auth.", + "parameters": { + "type": "params", + "required": ["actor"], + "properties": { + "actor": { + "type": "string", + "format": "at-identifier", + "description": "The account (actor) to check for membership." + }, + "limit": { + "type": "integer", + "minimum": 1, + "maximum": 100, + "default": 50 + }, + "cursor": { + "type": "string" + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["starterPacksWithMembership"], + "properties": { + "cursor": { + "type": "string" + }, + "starterPacksWithMembership": { + "type": "array", + "items": { + "type": "ref", + "ref": "#starterPackWithMembership" + } + } + } + } + } + }, + "starterPackWithMembership": { + "description": "A starter pack and an optional list item indicating membership of a target user to that starter pack.", + "type": "object", + "required": ["starterPack"], + "properties": { + "starterPack": { + "type": "ref", + "ref": "app.bsky.graph.defs#starterPackView" + }, + "listItem": { + "type": "ref", + "ref": "app.bsky.graph.defs#listItemView" + } + } + } + } +} diff --git a/lexicons/app/bsky/graph/getSuggestedFollowsByActor.json b/lexicons/app/bsky/graph/getSuggestedFollowsByActor.json new file mode 100644 index 0000000000..fcc141c88d --- /dev/null +++ b/lexicons/app/bsky/graph/getSuggestedFollowsByActor.json @@ -0,0 +1,49 @@ +{ + "lexicon": 1, + "id": "app.bsky.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": "app.bsky.actor.defs#profileView" + } + }, + "recIdStr": { + "type": "string", + "description": "Snowflake for this recommendation, use when submitting recommendation events." + }, + "isFallback": { + "type": "boolean", + "description": "DEPRECATED, unused. Previously: if true, response has fallen-back to generic results, and is not scoped using relativeToDid", + "default": false + }, + "recId": { + "type": "integer", + "description": "DEPRECATED: use recIdStr instead." + } + } + } + } + } + } +} diff --git a/lexicons/app/bsky/graph/list.json b/lexicons/app/bsky/graph/list.json new file mode 100644 index 0000000000..bec4e5919c --- /dev/null +++ b/lexicons/app/bsky/graph/list.json @@ -0,0 +1,53 @@ +{ + "lexicon": 1, + "id": "app.bsky.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": "app.bsky.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": "app.bsky.richtext.facet" + } + }, + "avatar": { + "type": "blob", + "accept": ["image/png", "image/jpeg"], + "maxSize": 1000000 + }, + "labels": { + "type": "union", + "refs": ["com.atproto.label.defs#selfLabels"] + }, + "createdAt": { + "type": "string", + "format": "datetime" + } + } + } + } + } +} diff --git a/lexicons/app/bsky/graph/listblock.json b/lexicons/app/bsky/graph/listblock.json new file mode 100644 index 0000000000..e448a3f846 --- /dev/null +++ b/lexicons/app/bsky/graph/listblock.json @@ -0,0 +1,26 @@ +{ + "lexicon": 1, + "id": "app.bsky.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" + } + } + } + } + } +} diff --git a/lexicons/app/bsky/graph/listitem.json b/lexicons/app/bsky/graph/listitem.json new file mode 100644 index 0000000000..54076a3bf2 --- /dev/null +++ b/lexicons/app/bsky/graph/listitem.json @@ -0,0 +1,31 @@ +{ + "lexicon": 1, + "id": "app.bsky.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 (app.bsky.graph.list)." + }, + "createdAt": { + "type": "string", + "format": "datetime" + } + } + } + } + } +} diff --git a/lexicons/app/bsky/graph/muteActor.json b/lexicons/app/bsky/graph/muteActor.json new file mode 100644 index 0000000000..44aa3b715d --- /dev/null +++ b/lexicons/app/bsky/graph/muteActor.json @@ -0,0 +1,23 @@ +{ + "lexicon": 1, + "id": "app.bsky.graph.muteActor", + "defs": { + "main": { + "type": "procedure", + "description": "Creates a mute relationship for the specified account. Mutes are private in Bluesky. Requires auth.", + "input": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["actor"], + "properties": { + "actor": { + "type": "string", + "format": "at-identifier" + } + } + } + } + } + } +} diff --git a/lexicons/app/bsky/graph/muteActorList.json b/lexicons/app/bsky/graph/muteActorList.json new file mode 100644 index 0000000000..af093a310e --- /dev/null +++ b/lexicons/app/bsky/graph/muteActorList.json @@ -0,0 +1,23 @@ +{ + "lexicon": 1, + "id": "app.bsky.graph.muteActorList", + "defs": { + "main": { + "type": "procedure", + "description": "Creates a mute relationship for the specified list of accounts. Mutes are private in Bluesky. Requires auth.", + "input": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["list"], + "properties": { + "list": { + "type": "string", + "format": "at-uri" + } + } + } + } + } + } +} diff --git a/lexicons/app/bsky/graph/muteThread.json b/lexicons/app/bsky/graph/muteThread.json new file mode 100644 index 0000000000..5e0c4c1c00 --- /dev/null +++ b/lexicons/app/bsky/graph/muteThread.json @@ -0,0 +1,23 @@ +{ + "lexicon": 1, + "id": "app.bsky.graph.muteThread", + "defs": { + "main": { + "type": "procedure", + "description": "Mutes a thread preventing notifications from the thread and any of its children. Mutes are private in Bluesky. Requires auth.", + "input": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["root"], + "properties": { + "root": { + "type": "string", + "format": "at-uri" + } + } + } + } + } + } +} diff --git a/lexicons/app/bsky/graph/searchStarterPacks.json b/lexicons/app/bsky/graph/searchStarterPacks.json new file mode 100644 index 0000000000..66a26ec45d --- /dev/null +++ b/lexicons/app/bsky/graph/searchStarterPacks.json @@ -0,0 +1,48 @@ +{ + "lexicon": 1, + "id": "app.bsky.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": "app.bsky.graph.defs#starterPackViewBasic" + } + } + } + } + } + } + } +} diff --git a/lexicons/app/bsky/graph/starterpack.json b/lexicons/app/bsky/graph/starterpack.json new file mode 100644 index 0000000000..3ee63ceb4a --- /dev/null +++ b/lexicons/app/bsky/graph/starterpack.json @@ -0,0 +1,63 @@ +{ + "lexicon": 1, + "id": "app.bsky.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": "app.bsky.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": "#feedItem" + } + }, + "createdAt": { + "type": "string", + "format": "datetime" + } + } + } + }, + "feedItem": { + "type": "object", + "required": ["uri"], + "properties": { + "uri": { + "type": "string", + "format": "at-uri" + } + } + } + } +} diff --git a/lexicons/app/bsky/graph/unmuteActor.json b/lexicons/app/bsky/graph/unmuteActor.json new file mode 100644 index 0000000000..719f164d63 --- /dev/null +++ b/lexicons/app/bsky/graph/unmuteActor.json @@ -0,0 +1,23 @@ +{ + "lexicon": 1, + "id": "app.bsky.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" + } + } + } + } + } + } +} diff --git a/lexicons/app/bsky/graph/unmuteActorList.json b/lexicons/app/bsky/graph/unmuteActorList.json new file mode 100644 index 0000000000..a9c94bf5f1 --- /dev/null +++ b/lexicons/app/bsky/graph/unmuteActorList.json @@ -0,0 +1,23 @@ +{ + "lexicon": 1, + "id": "app.bsky.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" + } + } + } + } + } + } +} diff --git a/lexicons/app/bsky/graph/unmuteThread.json b/lexicons/app/bsky/graph/unmuteThread.json new file mode 100644 index 0000000000..3953f9e867 --- /dev/null +++ b/lexicons/app/bsky/graph/unmuteThread.json @@ -0,0 +1,23 @@ +{ + "lexicon": 1, + "id": "app.bsky.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" + } + } + } + } + } + } +} diff --git a/lexicons/app/bsky/graph/verification.json b/lexicons/app/bsky/graph/verification.json new file mode 100644 index 0000000000..407da18e19 --- /dev/null +++ b/lexicons/app/bsky/graph/verification.json @@ -0,0 +1,36 @@ +{ + "lexicon": 1, + "id": "app.bsky.graph.verification", + "defs": { + "main": { + "type": "record", + "description": "Record declaring a verification relationship between two accounts. Verifications are only considered valid by an app if issued by an account the app considers trusted.", + "key": "tid", + "record": { + "type": "object", + "required": ["subject", "handle", "displayName", "createdAt"], + "properties": { + "subject": { + "description": "DID of the subject the verification applies to.", + "type": "string", + "format": "did" + }, + "handle": { + "description": "Handle of the subject the verification applies to at the moment of verifying, which might not be the same at the time of viewing. The verification is only valid if the current handle matches the one at the time of verifying.", + "type": "string", + "format": "handle" + }, + "displayName": { + "description": "Display name of the subject the verification applies to at the moment of verifying, which might not be the same at the time of viewing. The verification is only valid if the current displayName matches the one at the time of verifying.", + "type": "string" + }, + "createdAt": { + "description": "Date of when the verification was created.", + "type": "string", + "format": "datetime" + } + } + } + } + } +} diff --git a/lexicons/app/bsky/labeler/defs.json b/lexicons/app/bsky/labeler/defs.json new file mode 100644 index 0000000000..9fe89b7bc1 --- /dev/null +++ b/lexicons/app/bsky/labeler/defs.json @@ -0,0 +1,139 @@ +{ + "lexicon": 1, + "id": "app.bsky.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": "app.bsky.actor.defs#profileView" + }, + "likeCount": { + "type": "integer", + "minimum": 0 + }, + "viewer": { + "type": "ref", + "ref": "#labelerViewerState" + }, + "indexedAt": { + "type": "string", + "format": "datetime" + }, + "labels": { + "type": "array", + "items": { + "type": "ref", + "ref": "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": "app.bsky.actor.defs#profileView" + }, + "policies": { + "type": "ref", + "ref": "app.bsky.labeler.defs#labelerPolicies" + }, + "likeCount": { + "type": "integer", + "minimum": 0 + }, + "viewer": { + "type": "ref", + "ref": "#labelerViewerState" + }, + "indexedAt": { + "type": "string", + "format": "datetime" + }, + "labels": { + "type": "array", + "items": { + "type": "ref", + "ref": "com.atproto.label.defs#label" + } + }, + "reasonTypes": { + "description": "The set of report reason 'codes' which are in-scope for this service to review and action. These usually align to policy categories. If not defined (distinct from empty array), all reason types are allowed.", + "type": "array", + "items": { + "type": "ref", + "ref": "com.atproto.moderation.defs#reasonType" + } + }, + "subjectTypes": { + "description": "The set of subject types (account, record, etc) this service accepts reports on.", + "type": "array", + "items": { + "type": "ref", + "ref": "com.atproto.moderation.defs#subjectType" + } + }, + "subjectCollections": { + "type": "array", + "description": "Set of record types (collection NSIDs) which can be reported to this service. If not defined (distinct from empty array), default is any record type.", + "items": { + "type": "string", + "format": "nsid" + } + } + } + }, + "labelerViewerState": { + "type": "object", + "properties": { + "like": { + "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": "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": "com.atproto.label.defs#labelValueDefinition" + } + } + } + } + } +} diff --git a/lexicons/app/bsky/labeler/getServices.json b/lexicons/app/bsky/labeler/getServices.json new file mode 100644 index 0000000000..76752386c8 --- /dev/null +++ b/lexicons/app/bsky/labeler/getServices.json @@ -0,0 +1,46 @@ +{ + "lexicon": 1, + "id": "app.bsky.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": [ + "app.bsky.labeler.defs#labelerView", + "app.bsky.labeler.defs#labelerViewDetailed" + ] + } + } + } + } + } + } + } +} diff --git a/lexicons/app/bsky/labeler/service.json b/lexicons/app/bsky/labeler/service.json new file mode 100644 index 0000000000..680b3ebe52 --- /dev/null +++ b/lexicons/app/bsky/labeler/service.json @@ -0,0 +1,53 @@ +{ + "lexicon": 1, + "id": "app.bsky.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": "app.bsky.labeler.defs#labelerPolicies" + }, + "labels": { + "type": "union", + "refs": ["com.atproto.label.defs#selfLabels"] + }, + "createdAt": { + "type": "string", + "format": "datetime" + }, + "reasonTypes": { + "description": "The set of report reason 'codes' which are in-scope for this service to review and action. These usually align to policy categories. If not defined (distinct from empty array), all reason types are allowed.", + "type": "array", + "items": { + "type": "ref", + "ref": "com.atproto.moderation.defs#reasonType" + } + }, + "subjectTypes": { + "description": "The set of subject types (account, record, etc) this service accepts reports on.", + "type": "array", + "items": { + "type": "ref", + "ref": "com.atproto.moderation.defs#subjectType" + } + }, + "subjectCollections": { + "type": "array", + "description": "Set of record types (collection NSIDs) which can be reported to this service. If not defined (distinct from empty array), default is any record type.", + "items": { + "type": "string", + "format": "nsid" + } + } + } + } + } + } +} diff --git a/lexicons/app/bsky/notification/declaration.json b/lexicons/app/bsky/notification/declaration.json new file mode 100644 index 0000000000..6e6013ef45 --- /dev/null +++ b/lexicons/app/bsky/notification/declaration.json @@ -0,0 +1,22 @@ +{ + "lexicon": 1, + "id": "app.bsky.notification.declaration", + "defs": { + "main": { + "type": "record", + "description": "A declaration of the user's choices related to notifications that can be produced by them.", + "key": "literal:self", + "record": { + "type": "object", + "required": ["allowSubscriptions"], + "properties": { + "allowSubscriptions": { + "type": "string", + "description": "A declaration of the user's preference for allowing activity subscriptions from other users. Absence of a record implies 'followers'.", + "knownValues": ["followers", "mutuals", "none"] + } + } + } + } + } +} diff --git a/lexicons/app/bsky/notification/defs.json b/lexicons/app/bsky/notification/defs.json new file mode 100644 index 0000000000..e2c1969184 --- /dev/null +++ b/lexicons/app/bsky/notification/defs.json @@ -0,0 +1,152 @@ +{ + "lexicon": 1, + "id": "app.bsky.notification.defs", + "defs": { + "recordDeleted": { + "type": "object", + "properties": {} + }, + "chatPreference": { + "type": "object", + "description": "Deprecated: use chat.bsky.notification preferences instead. This will only return a default value.", + "required": ["include", "push"], + "properties": { + "include": { + "type": "string", + "knownValues": ["all", "accepted"] + }, + "push": { + "type": "boolean" + } + } + }, + "filterablePreference": { + "type": "object", + "required": ["include", "list", "push"], + "properties": { + "include": { + "type": "string", + "knownValues": ["all", "follows"] + }, + "list": { + "type": "boolean" + }, + "push": { + "type": "boolean" + } + } + }, + "preference": { + "type": "object", + "required": ["list", "push"], + "properties": { + "list": { + "type": "boolean" + }, + "push": { + "type": "boolean" + } + } + }, + "preferences": { + "type": "object", + "required": [ + "chat", + "follow", + "like", + "likeViaRepost", + "mention", + "quote", + "reply", + "repost", + "repostViaRepost", + "starterpackJoined", + "subscribedPost", + "unverified", + "verified" + ], + "properties": { + "chat": { + "type": "ref", + "ref": "#chatPreference", + "description": "Deprecated: use chat.bsky.notification preferences instead. This will only return a default value." + }, + "follow": { + "type": "ref", + "ref": "#filterablePreference" + }, + "like": { + "type": "ref", + "ref": "#filterablePreference" + }, + "likeViaRepost": { + "type": "ref", + "ref": "#filterablePreference" + }, + "mention": { + "type": "ref", + "ref": "#filterablePreference" + }, + "quote": { + "type": "ref", + "ref": "#filterablePreference" + }, + "reply": { + "type": "ref", + "ref": "#filterablePreference" + }, + "repost": { + "type": "ref", + "ref": "#filterablePreference" + }, + "repostViaRepost": { + "type": "ref", + "ref": "#filterablePreference" + }, + "starterpackJoined": { + "type": "ref", + "ref": "#preference" + }, + "subscribedPost": { + "type": "ref", + "ref": "#preference" + }, + "unverified": { + "type": "ref", + "ref": "#preference" + }, + "verified": { + "type": "ref", + "ref": "#preference" + } + } + }, + "activitySubscription": { + "type": "object", + "required": ["post", "reply"], + "properties": { + "post": { + "type": "boolean" + }, + "reply": { + "type": "boolean" + } + } + }, + "subjectActivitySubscription": { + "description": "Object used to store activity subscription data in stash.", + "type": "object", + "required": ["subject", "activitySubscription"], + "properties": { + "subject": { + "type": "string", + "format": "did" + }, + "activitySubscription": { + "type": "ref", + "ref": "#activitySubscription" + } + } + } + } +} diff --git a/lexicons/app/bsky/notification/getPreferences.json b/lexicons/app/bsky/notification/getPreferences.json new file mode 100644 index 0000000000..b482b3d3c8 --- /dev/null +++ b/lexicons/app/bsky/notification/getPreferences.json @@ -0,0 +1,27 @@ +{ + "lexicon": 1, + "id": "app.bsky.notification.getPreferences", + "defs": { + "main": { + "type": "query", + "description": "Get notification-related preferences for an account. Requires auth.", + "parameters": { + "type": "params", + "properties": {} + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["preferences"], + "properties": { + "preferences": { + "type": "ref", + "ref": "app.bsky.notification.defs#preferences" + } + } + } + } + } + } +} diff --git a/lexicons/app/bsky/notification/getUnreadCount.json b/lexicons/app/bsky/notification/getUnreadCount.json new file mode 100644 index 0000000000..f887584268 --- /dev/null +++ b/lexicons/app/bsky/notification/getUnreadCount.json @@ -0,0 +1,34 @@ +{ + "lexicon": 1, + "id": "app.bsky.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" + } + } + } + } + } + } +} diff --git a/lexicons/app/bsky/notification/listActivitySubscriptions.json b/lexicons/app/bsky/notification/listActivitySubscriptions.json new file mode 100644 index 0000000000..8ffff44c3c --- /dev/null +++ b/lexicons/app/bsky/notification/listActivitySubscriptions.json @@ -0,0 +1,43 @@ +{ + "lexicon": 1, + "id": "app.bsky.notification.listActivitySubscriptions", + "defs": { + "main": { + "type": "query", + "description": "Enumerate all accounts to which the requesting account is subscribed to receive notifications for. 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": ["subscriptions"], + "properties": { + "cursor": { + "type": "string" + }, + "subscriptions": { + "type": "array", + "items": { + "type": "ref", + "ref": "app.bsky.actor.defs#profileView" + } + } + } + } + } + } + } +} diff --git a/lexicons/app/bsky/notification/listNotifications.json b/lexicons/app/bsky/notification/listNotifications.json new file mode 100644 index 0000000000..adde811236 --- /dev/null +++ b/lexicons/app/bsky/notification/listNotifications.json @@ -0,0 +1,131 @@ +{ + "lexicon": 1, + "id": "app.bsky.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": "#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": "app.bsky.actor.defs#profileView" + }, + "reason": { + "type": "string", + "description": "The reason why this notification was delivered - e.g. your post was liked, or you received a new follower.", + "knownValues": [ + "like", + "repost", + "follow", + "mention", + "reply", + "quote", + "starterpack-joined", + "verified", + "unverified", + "like-via-repost", + "repost-via-repost", + "subscribed-post", + "contact-match" + ] + }, + "reasonSubject": { + "type": "string", + "format": "at-uri" + }, + "record": { + "type": "unknown" + }, + "isRead": { + "type": "boolean" + }, + "indexedAt": { + "type": "string", + "format": "datetime" + }, + "labels": { + "type": "array", + "items": { + "type": "ref", + "ref": "com.atproto.label.defs#label" + } + } + } + } + } +} diff --git a/lexicons/app/bsky/notification/putActivitySubscription.json b/lexicons/app/bsky/notification/putActivitySubscription.json new file mode 100644 index 0000000000..e7800fb136 --- /dev/null +++ b/lexicons/app/bsky/notification/putActivitySubscription.json @@ -0,0 +1,44 @@ +{ + "lexicon": 1, + "id": "app.bsky.notification.putActivitySubscription", + "defs": { + "main": { + "type": "procedure", + "description": "Puts an activity subscription entry. The key should be omitted for creation and provided for updates. Requires auth.", + "input": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["subject", "activitySubscription"], + "properties": { + "subject": { + "type": "string", + "format": "did" + }, + "activitySubscription": { + "type": "ref", + "ref": "app.bsky.notification.defs#activitySubscription" + } + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["subject"], + "properties": { + "subject": { + "type": "string", + "format": "did" + }, + "activitySubscription": { + "type": "ref", + "ref": "app.bsky.notification.defs#activitySubscription" + } + } + } + } + } + } +} diff --git a/lexicons/app/bsky/notification/putPreferences.json b/lexicons/app/bsky/notification/putPreferences.json new file mode 100644 index 0000000000..6e119950da --- /dev/null +++ b/lexicons/app/bsky/notification/putPreferences.json @@ -0,0 +1,22 @@ +{ + "lexicon": 1, + "id": "app.bsky.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" + } + } + } + } + } + } +} diff --git a/lexicons/app/bsky/notification/putPreferencesV2.json b/lexicons/app/bsky/notification/putPreferencesV2.json new file mode 100644 index 0000000000..848ff46d06 --- /dev/null +++ b/lexicons/app/bsky/notification/putPreferencesV2.json @@ -0,0 +1,84 @@ +{ + "lexicon": 1, + "id": "app.bsky.notification.putPreferencesV2", + "defs": { + "main": { + "type": "procedure", + "description": "Set notification-related preferences for an account. Requires auth.", + "input": { + "encoding": "application/json", + "schema": { + "type": "object", + "properties": { + "chat": { + "type": "ref", + "ref": "app.bsky.notification.defs#chatPreference", + "description": "Deprecated: use chat.bsky.notification preferences instead. Setting this won't stick and the default values will be returned." + }, + "follow": { + "type": "ref", + "ref": "app.bsky.notification.defs#filterablePreference" + }, + "like": { + "type": "ref", + "ref": "app.bsky.notification.defs#filterablePreference" + }, + "likeViaRepost": { + "type": "ref", + "ref": "app.bsky.notification.defs#filterablePreference" + }, + "mention": { + "type": "ref", + "ref": "app.bsky.notification.defs#filterablePreference" + }, + "quote": { + "type": "ref", + "ref": "app.bsky.notification.defs#filterablePreference" + }, + "reply": { + "type": "ref", + "ref": "app.bsky.notification.defs#filterablePreference" + }, + "repost": { + "type": "ref", + "ref": "app.bsky.notification.defs#filterablePreference" + }, + "repostViaRepost": { + "type": "ref", + "ref": "app.bsky.notification.defs#filterablePreference" + }, + "starterpackJoined": { + "type": "ref", + "ref": "app.bsky.notification.defs#preference" + }, + "subscribedPost": { + "type": "ref", + "ref": "app.bsky.notification.defs#preference" + }, + "unverified": { + "type": "ref", + "ref": "app.bsky.notification.defs#preference" + }, + "verified": { + "type": "ref", + "ref": "app.bsky.notification.defs#preference" + } + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["preferences"], + "properties": { + "preferences": { + "type": "ref", + "ref": "app.bsky.notification.defs#preferences" + } + } + } + } + } + } +} diff --git a/lexicons/app/bsky/notification/registerPush.json b/lexicons/app/bsky/notification/registerPush.json new file mode 100644 index 0000000000..d01e50470c --- /dev/null +++ b/lexicons/app/bsky/notification/registerPush.json @@ -0,0 +1,37 @@ +{ + "lexicon": 1, + "id": "app.bsky.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" + }, + "ageRestricted": { + "type": "boolean", + "description": "Set to true when the actor is age restricted" + } + } + } + } + } + } +} diff --git a/lexicons/app/bsky/notification/unregisterPush.json b/lexicons/app/bsky/notification/unregisterPush.json new file mode 100644 index 0000000000..0bd58eb086 --- /dev/null +++ b/lexicons/app/bsky/notification/unregisterPush.json @@ -0,0 +1,33 @@ +{ + "lexicon": 1, + "id": "app.bsky.notification.unregisterPush", + "defs": { + "main": { + "type": "procedure", + "description": "The inverse of registerPush - inform a specified service that push notifications should no longer be sent to the given token 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" + } + } + } + } + } + } +} diff --git a/lexicons/app/bsky/notification/updateSeen.json b/lexicons/app/bsky/notification/updateSeen.json new file mode 100644 index 0000000000..a443ce7610 --- /dev/null +++ b/lexicons/app/bsky/notification/updateSeen.json @@ -0,0 +1,23 @@ +{ + "lexicon": 1, + "id": "app.bsky.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" + } + } + } + } + } + } +} diff --git a/lexicons/app/bsky/richtext/facet.json b/lexicons/app/bsky/richtext/facet.json new file mode 100644 index 0000000000..edc5acaaea --- /dev/null +++ b/lexicons/app/bsky/richtext/facet.json @@ -0,0 +1,73 @@ +{ + "lexicon": 1, + "id": "app.bsky.richtext.facet", + "defs": { + "main": { + "type": "object", + "description": "Annotation of a sub-string within rich text.", + "required": ["index", "features"], + "properties": { + "index": { + "type": "ref", + "ref": "#byteSlice" + }, + "features": { + "type": "array", + "items": { + "type": "union", + "refs": ["#mention", "#link", "#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 + } + } + } + } +} diff --git a/lexicons/app/bsky/unspecced/defs.json b/lexicons/app/bsky/unspecced/defs.json new file mode 100644 index 0000000000..bdff995a19 --- /dev/null +++ b/lexicons/app/bsky/unspecced/defs.json @@ -0,0 +1,253 @@ +{ + "lexicon": 1, + "id": "app.bsky.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" + } + } + }, + "skeletonTrend": { + "type": "object", + "required": [ + "topic", + "displayName", + "link", + "startedAt", + "postCount", + "dids" + ], + "properties": { + "topic": { + "type": "string" + }, + "displayName": { + "type": "string" + }, + "link": { + "type": "string" + }, + "startedAt": { + "type": "string", + "format": "datetime" + }, + "postCount": { + "type": "integer" + }, + "status": { + "type": "string", + "knownValues": ["hot"] + }, + "category": { + "type": "string" + }, + "dids": { + "type": "array", + "items": { + "type": "string", + "format": "did" + } + } + } + }, + "trendView": { + "type": "object", + "required": [ + "topic", + "displayName", + "link", + "startedAt", + "postCount", + "actors" + ], + "properties": { + "topic": { + "type": "string" + }, + "displayName": { + "type": "string" + }, + "link": { + "type": "string" + }, + "startedAt": { + "type": "string", + "format": "datetime" + }, + "postCount": { + "type": "integer" + }, + "status": { + "type": "string", + "knownValues": ["hot"] + }, + "category": { + "type": "string" + }, + "actors": { + "type": "array", + "items": { + "type": "ref", + "ref": "app.bsky.actor.defs#profileViewBasic" + } + } + } + }, + "threadItemPost": { + "type": "object", + "required": [ + "post", + "moreParents", + "moreReplies", + "opThread", + "hiddenByThreadgate", + "mutedByViewer" + ], + "properties": { + "post": { + "type": "ref", + "ref": "app.bsky.feed.defs#postView" + }, + "moreParents": { + "type": "boolean", + "description": "This post has more parents that were not present in the response. This is just a boolean, without the number of parents." + }, + "moreReplies": { + "type": "integer", + "description": "This post has more replies that were not present in the response. This is a numeric value, which is best-effort and might not be accurate." + }, + "opThread": { + "type": "boolean", + "description": "This post is part of a contiguous thread by the OP from the thread root. Many different OP threads can happen in the same thread." + }, + "hiddenByThreadgate": { + "type": "boolean", + "description": "The threadgate created by the author indicates this post as a reply to be hidden for everyone consuming the thread." + }, + "mutedByViewer": { + "type": "boolean", + "description": "This is by an account muted by the viewer requesting it." + } + } + }, + "threadItemNoUnauthenticated": { + "type": "object", + "properties": {} + }, + "threadItemNotFound": { + "type": "object", + "properties": {} + }, + "threadItemBlocked": { + "type": "object", + "required": ["author"], + "properties": { + "author": { + "type": "ref", + "ref": "app.bsky.feed.defs#blockedAuthor" + } + } + }, + "ageAssuranceState": { + "type": "object", + "description": "The computed state of the age assurance process, returned to the user in question on certain authenticated requests.", + "required": ["status"], + "properties": { + "lastInitiatedAt": { + "type": "string", + "format": "datetime", + "description": "The timestamp when this state was last updated." + }, + "status": { + "type": "string", + "description": "The status of the age assurance process.", + "knownValues": ["unknown", "pending", "assured", "blocked"] + } + } + }, + "ageAssuranceEvent": { + "type": "object", + "description": "Object used to store age assurance data in stash.", + "required": ["createdAt", "status", "attemptId"], + "properties": { + "createdAt": { + "type": "string", + "format": "datetime", + "description": "The date and time of this write operation." + }, + "status": { + "type": "string", + "description": "The status of the age assurance process.", + "knownValues": ["unknown", "pending", "assured"] + }, + "attemptId": { + "type": "string", + "description": "The unique identifier for this instance of the age assurance flow, in UUID format." + }, + "email": { + "type": "string", + "description": "The email used for AA." + }, + "initIp": { + "type": "string", + "description": "The IP address used when initiating the AA flow." + }, + "initUa": { + "type": "string", + "description": "The user agent used when initiating the AA flow." + }, + "completeIp": { + "type": "string", + "description": "The IP address used when completing the AA flow." + }, + "completeUa": { + "type": "string", + "description": "The user agent used when completing the AA flow." + } + } + } + } +} diff --git a/lexicons/app/bsky/unspecced/getAgeAssuranceState.json b/lexicons/app/bsky/unspecced/getAgeAssuranceState.json new file mode 100644 index 0000000000..3bd42b3246 --- /dev/null +++ b/lexicons/app/bsky/unspecced/getAgeAssuranceState.json @@ -0,0 +1,17 @@ +{ + "lexicon": 1, + "id": "app.bsky.unspecced.getAgeAssuranceState", + "defs": { + "main": { + "type": "query", + "description": "Returns the current state of the age assurance process for an account. This is used to check if the user has completed age assurance or if further action is required.", + "output": { + "encoding": "application/json", + "schema": { + "type": "ref", + "ref": "app.bsky.unspecced.defs#ageAssuranceState" + } + } + } + } +} diff --git a/lexicons/app/bsky/unspecced/getConfig.json b/lexicons/app/bsky/unspecced/getConfig.json new file mode 100644 index 0000000000..1e40f80dc2 --- /dev/null +++ b/lexicons/app/bsky/unspecced/getConfig.json @@ -0,0 +1,45 @@ +{ + "lexicon": 1, + "id": "app.bsky.unspecced.getConfig", + "defs": { + "main": { + "type": "query", + "description": "Get miscellaneous runtime configuration.", + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": [], + "properties": { + "checkEmailConfirmed": { + "type": "boolean" + }, + "liveNow": { + "type": "array", + "items": { + "type": "ref", + "ref": "#liveNowConfig" + } + } + } + } + } + }, + "liveNowConfig": { + "type": "object", + "required": ["did", "domains"], + "properties": { + "did": { + "type": "string", + "format": "did" + }, + "domains": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + } +} diff --git a/lexicons/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.json b/lexicons/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.json new file mode 100644 index 0000000000..60b1490137 --- /dev/null +++ b/lexicons/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.json @@ -0,0 +1,37 @@ +{ + "lexicon": 1, + "id": "app.bsky.unspecced.getOnboardingSuggestedStarterPacks", + "defs": { + "main": { + "type": "query", + "description": "Get a list of suggested starterpacks for onboarding", + "parameters": { + "type": "params", + "properties": { + "limit": { + "type": "integer", + "minimum": 1, + "maximum": 25, + "default": 10 + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["starterPacks"], + "properties": { + "starterPacks": { + "type": "array", + "items": { + "type": "ref", + "ref": "app.bsky.graph.defs#starterPackView" + } + } + } + } + } + } + } +} diff --git a/lexicons/app/bsky/unspecced/getPopularFeedGenerators.json b/lexicons/app/bsky/unspecced/getPopularFeedGenerators.json new file mode 100644 index 0000000000..407ff66e3a --- /dev/null +++ b/lexicons/app/bsky/unspecced/getPopularFeedGenerators.json @@ -0,0 +1,46 @@ +{ + "lexicon": 1, + "id": "app.bsky.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": "app.bsky.feed.defs#generatorView" + } + } + } + } + } + } + } +} diff --git a/lexicons/app/bsky/unspecced/getPostThreadOtherV2.json b/lexicons/app/bsky/unspecced/getPostThreadOtherV2.json new file mode 100644 index 0000000000..7fab28bfeb --- /dev/null +++ b/lexicons/app/bsky/unspecced/getPostThreadOtherV2.json @@ -0,0 +1,56 @@ +{ + "lexicon": 1, + "id": "app.bsky.unspecced.getPostThreadOtherV2", + "defs": { + "main": { + "type": "query", + "description": "(NOTE: this endpoint is under development and WILL change without notice. Don't use it until it is moved out of `unspecced` or your application WILL break) Get additional posts under a thread e.g. replies hidden by threadgate. Based on an anchor post at any depth of the tree, returns top-level replies below that anchor. It does not include ancestors nor the anchor itself. This should be called after exhausting `app.bsky.unspecced.getPostThreadV2`. Does not require auth, but additional metadata and filtering will be applied for authed requests.", + "parameters": { + "type": "params", + "required": ["anchor"], + "properties": { + "anchor": { + "type": "string", + "format": "at-uri", + "description": "Reference (AT-URI) to post record. This is the anchor post." + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["thread"], + "properties": { + "thread": { + "type": "array", + "description": "A flat list of other thread items. The depth of each item is indicated by the depth property inside the item.", + "items": { + "type": "ref", + "ref": "#threadItem" + } + } + } + } + } + }, + "threadItem": { + "type": "object", + "required": ["uri", "depth", "value"], + "properties": { + "uri": { + "type": "string", + "format": "at-uri" + }, + "depth": { + "type": "integer", + "description": "The nesting level of this item in the thread. Depth 0 means the anchor item. Items above have negative depths, items below have positive depths." + }, + "value": { + "type": "union", + "refs": ["app.bsky.unspecced.defs#threadItemPost"] + } + } + } + } +} diff --git a/lexicons/app/bsky/unspecced/getPostThreadV2.json b/lexicons/app/bsky/unspecced/getPostThreadV2.json new file mode 100644 index 0000000000..e38dfde964 --- /dev/null +++ b/lexicons/app/bsky/unspecced/getPostThreadV2.json @@ -0,0 +1,94 @@ +{ + "lexicon": 1, + "id": "app.bsky.unspecced.getPostThreadV2", + "defs": { + "main": { + "type": "query", + "description": "(NOTE: this endpoint is under development and WILL change without notice. Don't use it until it is moved out of `unspecced` or your application WILL break) Get posts in a thread. It is based in an anchor post at any depth of the tree, and returns posts above it (recursively resolving the parent, without further branching to their replies) and below it (recursive replies, with branching to their replies). Does not require auth, but additional metadata and filtering will be applied for authed requests.", + "parameters": { + "type": "params", + "required": ["anchor"], + "properties": { + "anchor": { + "type": "string", + "format": "at-uri", + "description": "Reference (AT-URI) to post record. This is the anchor post, and the thread will be built around it. It can be any post in the tree, not necessarily a root post." + }, + "above": { + "type": "boolean", + "description": "Whether to include parents above the anchor.", + "default": true + }, + "below": { + "type": "integer", + "description": "How many levels of replies to include below the anchor.", + "default": 6, + "minimum": 0, + "maximum": 20 + }, + "branchingFactor": { + "type": "integer", + "description": "Maximum of replies to include at each level of the thread, except for the direct replies to the anchor, which are (NOTE: currently, during unspecced phase) all returned (NOTE: later they might be paginated).", + "default": 10, + "minimum": 0, + "maximum": 100 + }, + "sort": { + "type": "string", + "description": "Sorting for the thread replies.", + "knownValues": ["newest", "oldest", "top"], + "default": "oldest" + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["thread", "hasOtherReplies"], + "properties": { + "thread": { + "type": "array", + "description": "A flat list of thread items. The depth of each item is indicated by the depth property inside the item.", + "items": { + "type": "ref", + "ref": "#threadItem" + } + }, + "threadgate": { + "type": "ref", + "ref": "app.bsky.feed.defs#threadgateView" + }, + "hasOtherReplies": { + "type": "boolean", + "description": "Whether this thread has additional replies. If true, a call can be made to the `getPostThreadOtherV2` endpoint to retrieve them." + } + } + } + } + }, + "threadItem": { + "type": "object", + "required": ["uri", "depth", "value"], + "properties": { + "uri": { + "type": "string", + "format": "at-uri" + }, + "depth": { + "type": "integer", + "description": "The nesting level of this item in the thread. Depth 0 means the anchor item. Items above have negative depths, items below have positive depths." + }, + "value": { + "type": "union", + "refs": [ + "app.bsky.unspecced.defs#threadItemPost", + "app.bsky.unspecced.defs#threadItemNoUnauthenticated", + "app.bsky.unspecced.defs#threadItemNotFound", + "app.bsky.unspecced.defs#threadItemBlocked" + ] + } + } + } + } +} diff --git a/lexicons/app/bsky/unspecced/getSuggestedFeeds.json b/lexicons/app/bsky/unspecced/getSuggestedFeeds.json new file mode 100644 index 0000000000..1a723a0bbb --- /dev/null +++ b/lexicons/app/bsky/unspecced/getSuggestedFeeds.json @@ -0,0 +1,37 @@ +{ + "lexicon": 1, + "id": "app.bsky.unspecced.getSuggestedFeeds", + "defs": { + "main": { + "type": "query", + "description": "Get a list of suggested feeds", + "parameters": { + "type": "params", + "properties": { + "limit": { + "type": "integer", + "minimum": 1, + "maximum": 25, + "default": 10 + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["feeds"], + "properties": { + "feeds": { + "type": "array", + "items": { + "type": "ref", + "ref": "app.bsky.feed.defs#generatorView" + } + } + } + } + } + } + } +} diff --git a/lexicons/app/bsky/unspecced/getSuggestedFeedsSkeleton.json b/lexicons/app/bsky/unspecced/getSuggestedFeedsSkeleton.json new file mode 100644 index 0000000000..c0b72da680 --- /dev/null +++ b/lexicons/app/bsky/unspecced/getSuggestedFeedsSkeleton.json @@ -0,0 +1,42 @@ +{ + "lexicon": 1, + "id": "app.bsky.unspecced.getSuggestedFeedsSkeleton", + "defs": { + "main": { + "type": "query", + "description": "Get a skeleton of suggested feeds. Intended to be called and hydrated by app.bsky.unspecced.getSuggestedFeeds", + "parameters": { + "type": "params", + "properties": { + "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": 25, + "default": 10 + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["feeds"], + "properties": { + "feeds": { + "type": "array", + "items": { + "type": "string", + "format": "at-uri" + } + } + } + } + } + } + } +} diff --git a/lexicons/app/bsky/unspecced/getSuggestedStarterPacks.json b/lexicons/app/bsky/unspecced/getSuggestedStarterPacks.json new file mode 100644 index 0000000000..d4bdd22643 --- /dev/null +++ b/lexicons/app/bsky/unspecced/getSuggestedStarterPacks.json @@ -0,0 +1,37 @@ +{ + "lexicon": 1, + "id": "app.bsky.unspecced.getSuggestedStarterPacks", + "defs": { + "main": { + "type": "query", + "description": "Get a list of suggested starterpacks", + "parameters": { + "type": "params", + "properties": { + "limit": { + "type": "integer", + "minimum": 1, + "maximum": 25, + "default": 10 + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["starterPacks"], + "properties": { + "starterPacks": { + "type": "array", + "items": { + "type": "ref", + "ref": "app.bsky.graph.defs#starterPackView" + } + } + } + } + } + } + } +} diff --git a/lexicons/app/bsky/unspecced/getSuggestedStarterPacksSkeleton.json b/lexicons/app/bsky/unspecced/getSuggestedStarterPacksSkeleton.json new file mode 100644 index 0000000000..cf5d88e060 --- /dev/null +++ b/lexicons/app/bsky/unspecced/getSuggestedStarterPacksSkeleton.json @@ -0,0 +1,42 @@ +{ + "lexicon": 1, + "id": "app.bsky.unspecced.getSuggestedStarterPacksSkeleton", + "defs": { + "main": { + "type": "query", + "description": "Get a skeleton of suggested starterpacks. Intended to be called and hydrated by app.bsky.unspecced.getSuggestedStarterpacks", + "parameters": { + "type": "params", + "properties": { + "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": 25, + "default": 10 + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["starterPacks"], + "properties": { + "starterPacks": { + "type": "array", + "items": { + "type": "string", + "format": "at-uri" + } + } + } + } + } + } + } +} diff --git a/lexicons/app/bsky/unspecced/getSuggestedUsers.json b/lexicons/app/bsky/unspecced/getSuggestedUsers.json new file mode 100644 index 0000000000..705e21c9d6 --- /dev/null +++ b/lexicons/app/bsky/unspecced/getSuggestedUsers.json @@ -0,0 +1,49 @@ +{ + "lexicon": 1, + "id": "app.bsky.unspecced.getSuggestedUsers", + "defs": { + "main": { + "type": "query", + "description": "Get a list of suggested users", + "parameters": { + "type": "params", + "properties": { + "category": { + "type": "string", + "description": "Category of users to get suggestions for." + }, + "limit": { + "type": "integer", + "minimum": 1, + "maximum": 50, + "default": 25 + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["actors"], + "properties": { + "actors": { + "type": "array", + "items": { + "type": "ref", + "ref": "app.bsky.actor.defs#profileView" + } + }, + "recId": { + "type": "string", + "description": "DEPRECATED: use recIdStr instead." + }, + "recIdStr": { + "type": "string", + "description": "Snowflake for this recommendation, use when submitting recommendation events." + } + } + } + } + } + } +} diff --git a/lexicons/app/bsky/unspecced/getSuggestedUsersSkeleton.json b/lexicons/app/bsky/unspecced/getSuggestedUsersSkeleton.json new file mode 100644 index 0000000000..3fed8dd95d --- /dev/null +++ b/lexicons/app/bsky/unspecced/getSuggestedUsersSkeleton.json @@ -0,0 +1,54 @@ +{ + "lexicon": 1, + "id": "app.bsky.unspecced.getSuggestedUsersSkeleton", + "defs": { + "main": { + "type": "query", + "description": "Get a skeleton of suggested users. Intended to be called and hydrated by app.bsky.unspecced.getSuggestedUsers", + "parameters": { + "type": "params", + "properties": { + "viewer": { + "type": "string", + "format": "did", + "description": "DID of the account making the request (not included for public/unauthenticated queries)." + }, + "category": { + "type": "string", + "description": "Category of users to get suggestions for." + }, + "limit": { + "type": "integer", + "minimum": 1, + "maximum": 50, + "default": 25 + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["dids"], + "properties": { + "dids": { + "type": "array", + "items": { + "type": "string", + "format": "did" + } + }, + "recId": { + "type": "string", + "description": "DEPRECATED: use recIdStr instead." + }, + "recIdStr": { + "type": "string", + "description": "Snowflake for this recommendation, use when submitting recommendation events." + } + } + } + } + } + } +} diff --git a/lexicons/app/bsky/unspecced/getSuggestionsSkeleton.json b/lexicons/app/bsky/unspecced/getSuggestionsSkeleton.json new file mode 100644 index 0000000000..466815ed47 --- /dev/null +++ b/lexicons/app/bsky/unspecced/getSuggestionsSkeleton.json @@ -0,0 +1,66 @@ +{ + "lexicon": 1, + "id": "app.bsky.unspecced.getSuggestionsSkeleton", + "defs": { + "main": { + "type": "query", + "description": "Get a skeleton of suggested actors. Intended to be called and then hydrated through app.bsky.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": "app.bsky.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": "DEPRECATED: use recIdStr instead." + }, + "recIdStr": { + "type": "string", + "description": "Snowflake for this recommendation, use when submitting recommendation events." + } + } + } + } + } + } +} diff --git a/lexicons/app/bsky/unspecced/getTaggedSuggestions.json b/lexicons/app/bsky/unspecced/getTaggedSuggestions.json new file mode 100644 index 0000000000..f81459098d --- /dev/null +++ b/lexicons/app/bsky/unspecced/getTaggedSuggestions.json @@ -0,0 +1,47 @@ +{ + "lexicon": 1, + "id": "app.bsky.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": "#suggestion" + } + } + } + } + } + }, + "suggestion": { + "type": "object", + "required": ["tag", "subjectType", "subject"], + "properties": { + "tag": { + "type": "string" + }, + "subjectType": { + "type": "string", + "knownValues": ["actor", "feed"] + }, + "subject": { + "type": "string", + "format": "uri" + } + } + } + } +} diff --git a/lexicons/app/bsky/unspecced/getTrendingTopics.json b/lexicons/app/bsky/unspecced/getTrendingTopics.json new file mode 100644 index 0000000000..097dc1c54d --- /dev/null +++ b/lexicons/app/bsky/unspecced/getTrendingTopics.json @@ -0,0 +1,49 @@ +{ + "lexicon": 1, + "id": "app.bsky.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": "app.bsky.unspecced.defs#trendingTopic" + } + }, + "suggested": { + "type": "array", + "items": { + "type": "ref", + "ref": "app.bsky.unspecced.defs#trendingTopic" + } + } + } + } + } + } + } +} diff --git a/lexicons/app/bsky/unspecced/getTrends.json b/lexicons/app/bsky/unspecced/getTrends.json new file mode 100644 index 0000000000..1c114218a4 --- /dev/null +++ b/lexicons/app/bsky/unspecced/getTrends.json @@ -0,0 +1,37 @@ +{ + "lexicon": 1, + "id": "app.bsky.unspecced.getTrends", + "defs": { + "main": { + "type": "query", + "description": "Get the current trends on the network", + "parameters": { + "type": "params", + "properties": { + "limit": { + "type": "integer", + "minimum": 1, + "maximum": 25, + "default": 10 + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["trends"], + "properties": { + "trends": { + "type": "array", + "items": { + "type": "ref", + "ref": "app.bsky.unspecced.defs#trendView" + } + } + } + } + } + } + } +} diff --git a/lexicons/app/bsky/unspecced/getTrendsSkeleton.json b/lexicons/app/bsky/unspecced/getTrendsSkeleton.json new file mode 100644 index 0000000000..d0b6272bb6 --- /dev/null +++ b/lexicons/app/bsky/unspecced/getTrendsSkeleton.json @@ -0,0 +1,42 @@ +{ + "lexicon": 1, + "id": "app.bsky.unspecced.getTrendsSkeleton", + "defs": { + "main": { + "type": "query", + "description": "Get the skeleton of trends on the network. Intended to be called and then hydrated through app.bsky.unspecced.getTrends", + "parameters": { + "type": "params", + "properties": { + "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": 25, + "default": 10 + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["trends"], + "properties": { + "trends": { + "type": "array", + "items": { + "type": "ref", + "ref": "app.bsky.unspecced.defs#skeletonTrend" + } + } + } + } + } + } + } +} diff --git a/lexicons/app/bsky/unspecced/initAgeAssurance.json b/lexicons/app/bsky/unspecced/initAgeAssurance.json new file mode 100644 index 0000000000..236c07cf36 --- /dev/null +++ b/lexicons/app/bsky/unspecced/initAgeAssurance.json @@ -0,0 +1,49 @@ +{ + "lexicon": 1, + "id": "app.bsky.unspecced.initAgeAssurance", + "defs": { + "main": { + "type": "procedure", + "description": "Initiate age assurance for an account. This is a one-time action that will start the process of verifying the user's age.", + "input": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["email", "language", "countryCode"], + "properties": { + "email": { + "type": "string", + "description": "The user's email address to receive assurance instructions." + }, + "language": { + "type": "string", + "description": "The user's preferred language for communication during the assurance process." + }, + "countryCode": { + "type": "string", + "description": "An ISO 3166-1 alpha-2 code of the user's location." + } + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "ref", + "ref": "app.bsky.unspecced.defs#ageAssuranceState" + } + }, + "errors": [ + { + "name": "InvalidEmail" + }, + { + "name": "DidTooLong" + }, + { + "name": "InvalidInitiation" + } + ] + } + } +} diff --git a/lexicons/app/bsky/unspecced/searchActorsSkeleton.json b/lexicons/app/bsky/unspecced/searchActorsSkeleton.json new file mode 100644 index 0000000000..71784336a3 --- /dev/null +++ b/lexicons/app/bsky/unspecced/searchActorsSkeleton.json @@ -0,0 +1,67 @@ +{ + "lexicon": 1, + "id": "app.bsky.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": "app.bsky.unspecced.defs#skeletonSearchActor" + } + } + } + } + }, + "errors": [ + { + "name": "BadQueryString" + } + ] + } + } +} diff --git a/lexicons/app/bsky/unspecced/searchPostsSkeleton.json b/lexicons/app/bsky/unspecced/searchPostsSkeleton.json new file mode 100644 index 0000000000..63c3cf4858 --- /dev/null +++ b/lexicons/app/bsky/unspecced/searchPostsSkeleton.json @@ -0,0 +1,110 @@ +{ + "lexicon": 1, + "id": "app.bsky.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": "app.bsky.unspecced.defs#skeletonSearchPost" + } + } + } + } + }, + "errors": [ + { + "name": "BadQueryString" + } + ] + } + } +} diff --git a/lexicons/app/bsky/unspecced/searchStarterPacksSkeleton.json b/lexicons/app/bsky/unspecced/searchStarterPacksSkeleton.json new file mode 100644 index 0000000000..80c1b88179 --- /dev/null +++ b/lexicons/app/bsky/unspecced/searchStarterPacksSkeleton.json @@ -0,0 +1,63 @@ +{ + "lexicon": 1, + "id": "app.bsky.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": "app.bsky.unspecced.defs#skeletonSearchStarterPack" + } + } + } + } + }, + "errors": [ + { + "name": "BadQueryString" + } + ] + } + } +} diff --git a/lexicons/app/bsky/video/defs.json b/lexicons/app/bsky/video/defs.json new file mode 100644 index 0000000000..37cbcb1cca --- /dev/null +++ b/lexicons/app/bsky/video/defs.json @@ -0,0 +1,39 @@ +{ + "lexicon": 1, + "id": "app.bsky.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" + } + } + } + } +} diff --git a/lexicons/app/bsky/video/getJobStatus.json b/lexicons/app/bsky/video/getJobStatus.json new file mode 100644 index 0000000000..ff3076f2a0 --- /dev/null +++ b/lexicons/app/bsky/video/getJobStatus.json @@ -0,0 +1,32 @@ +{ + "lexicon": 1, + "id": "app.bsky.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": "app.bsky.video.defs#jobStatus" + } + } + } + } + } + } +} diff --git a/lexicons/app/bsky/video/getUploadLimits.json b/lexicons/app/bsky/video/getUploadLimits.json new file mode 100644 index 0000000000..374fbb3643 --- /dev/null +++ b/lexicons/app/bsky/video/getUploadLimits.json @@ -0,0 +1,34 @@ +{ + "lexicon": 1, + "id": "app.bsky.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" + } + } + } + } + } + } +} diff --git a/lexicons/app/bsky/video/uploadVideo.json b/lexicons/app/bsky/video/uploadVideo.json new file mode 100644 index 0000000000..8ffc26462d --- /dev/null +++ b/lexicons/app/bsky/video/uploadVideo.json @@ -0,0 +1,26 @@ +{ + "lexicon": 1, + "id": "app.bsky.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": "app.bsky.video.defs#jobStatus" + } + } + } + } + } + } +} diff --git a/lexicons/chat/bsky/actor/declaration.json b/lexicons/chat/bsky/actor/declaration.json new file mode 100644 index 0000000000..b5b5a10e4a --- /dev/null +++ b/lexicons/chat/bsky/actor/declaration.json @@ -0,0 +1,26 @@ +{ + "lexicon": 1, + "id": "chat.bsky.actor.declaration", + "defs": { + "main": { + "type": "record", + "description": "A declaration of a Bluesky chat account.", + "key": "literal:self", + "record": { + "type": "object", + "required": ["allowIncoming"], + "properties": { + "allowIncoming": { + "type": "string", + "knownValues": ["all", "none", "following"] + }, + "allowGroupInvites": { + "description": "Declaration about group chat invitation preferences for the record owner.", + "type": "string", + "knownValues": ["all", "none", "following"] + } + } + } + } + } +} diff --git a/lexicons/chat/bsky/actor/defs.json b/lexicons/chat/bsky/actor/defs.json new file mode 100644 index 0000000000..7812dce6e2 --- /dev/null +++ b/lexicons/chat/bsky/actor/defs.json @@ -0,0 +1,96 @@ +{ + "lexicon": 1, + "id": "chat.bsky.actor.defs", + "defs": { + "memberRole": { + "type": "string", + "knownValues": ["owner", "standard"] + }, + "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": "app.bsky.actor.defs#profileAssociated" + }, + "viewer": { + "type": "ref", + "ref": "app.bsky.actor.defs#viewerState" + }, + "labels": { + "type": "array", + "items": { + "type": "ref", + "ref": "com.atproto.label.defs#label" + } + }, + "createdAt": { + "type": "string", + "format": "datetime" + }, + "chatDisabled": { + "type": "boolean", + "description": "Set to true when the actor cannot actively participate in conversations" + }, + "verification": { + "type": "ref", + "ref": "app.bsky.actor.defs#verificationState" + }, + "kind": { + "description": "Union field that has data specific to different kinds of convos.", + "type": "union", + "refs": [ + "#directConvoMember", + "#groupConvoMember", + "#pastGroupConvoMember" + ] + } + } + }, + "directConvoMember": { + "type": "object", + "properties": {} + }, + "groupConvoMember": { + "description": "A current group convo member.", + "type": "object", + "required": ["role"], + "properties": { + "addedBy": { + "description": "Who added this member. Only present if the member was added (instead of joining via link).", + "type": "ref", + "ref": "#profileViewBasic" + }, + "role": { + "description": "The member's role within this conversation. Only present in group conversation member lists.", + "type": "ref", + "ref": "#memberRole" + } + } + }, + "pastGroupConvoMember": { + "description": "A past group convo member.", + "type": "object", + "required": [], + "properties": {} + } + } +} diff --git a/lexicons/chat/bsky/actor/deleteAccount.json b/lexicons/chat/bsky/actor/deleteAccount.json new file mode 100644 index 0000000000..115508157b --- /dev/null +++ b/lexicons/chat/bsky/actor/deleteAccount.json @@ -0,0 +1,16 @@ +{ + "lexicon": 1, + "id": "chat.bsky.actor.deleteAccount", + "defs": { + "main": { + "type": "procedure", + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "properties": {} + } + } + } + } +} diff --git a/lexicons/chat/bsky/actor/exportAccountData.json b/lexicons/chat/bsky/actor/exportAccountData.json new file mode 100644 index 0000000000..9716aa8fc2 --- /dev/null +++ b/lexicons/chat/bsky/actor/exportAccountData.json @@ -0,0 +1,12 @@ +{ + "lexicon": 1, + "id": "chat.bsky.actor.exportAccountData", + "defs": { + "main": { + "type": "query", + "output": { + "encoding": "application/jsonl" + } + } + } +} diff --git a/lexicons/chat/bsky/actor/getStatus.json b/lexicons/chat/bsky/actor/getStatus.json new file mode 100644 index 0000000000..300aa98f32 --- /dev/null +++ b/lexicons/chat/bsky/actor/getStatus.json @@ -0,0 +1,31 @@ +{ + "lexicon": 1, + "id": "chat.bsky.actor.getStatus", + "defs": { + "main": { + "type": "query", + "description": "Get the authenticated viewer's chat status: whether their account is chat-disabled and whether their group-membership additions are restricted to accounts they follow.", + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["chatDisabled", "canCreateGroups", "groupMemberLimit"], + "properties": { + "chatDisabled": { + "type": "boolean", + "description": "True when the viewer's account is disabled and cannot actively participate in chat." + }, + "canCreateGroups": { + "type": "boolean", + "description": "Whether the viewer's account is allowed to create group chats. New accounts are restricted from creating groups." + }, + "groupMemberLimit": { + "type": "integer", + "description": "The maximum number of members allowed in a group conversation." + } + } + } + } + } + } +} diff --git a/lexicons/chat/bsky/authFullChatClient.json b/lexicons/chat/bsky/authFullChatClient.json new file mode 100644 index 0000000000..4ace1b5813 --- /dev/null +++ b/lexicons/chat/bsky/authFullChatClient.json @@ -0,0 +1,69 @@ +{ + "lexicon": 1, + "id": "chat.bsky.authFullChatClient", + "defs": { + "main": { + "type": "permission-set", + "title": "Full Chat Client (All Conversations)", + "title:lang": {}, + "detail": "Control of all chat conversations and configuration management.", + "detail:lang": { + "en": "All Chat Conversations" + }, + "permissions": [ + { + "type": "permission", + "resource": "rpc", + "inheritAud": true, + "lxm": [ + "chat.bsky.actor.deleteAccount", + "chat.bsky.actor.getStatus", + "chat.bsky.convo.acceptConvo", + "chat.bsky.convo.addReaction", + "chat.bsky.convo.deleteMessageForSelf", + "chat.bsky.convo.exportAccountData", + "chat.bsky.convo.getConvo", + "chat.bsky.convo.getConvoAvailability", + "chat.bsky.convo.getConvoForMembers", + "chat.bsky.convo.getConvoMembers", + "chat.bsky.convo.getLog", + "chat.bsky.convo.getMessages", + "chat.bsky.convo.leaveConvo", + "chat.bsky.convo.listConvoRequests", + "chat.bsky.convo.listConvos", + "chat.bsky.convo.lockConvo", + "chat.bsky.convo.muteConvo", + "chat.bsky.convo.removeReaction", + "chat.bsky.convo.sendMessage", + "chat.bsky.convo.sendMessageBatch", + "chat.bsky.convo.unlockConvo", + "chat.bsky.convo.unmuteConvo", + "chat.bsky.convo.updateAllRead", + "chat.bsky.convo.updateRead", + "chat.bsky.group.addMembers", + "chat.bsky.group.approveJoinRequest", + "chat.bsky.group.createGroup", + "chat.bsky.group.createJoinLink", + "chat.bsky.group.disableJoinLink", + "chat.bsky.group.editGroup", + "chat.bsky.group.editJoinLink", + "chat.bsky.group.enableJoinLink", + "chat.bsky.group.getJoinLinkPreviews", + "chat.bsky.group.listJoinRequests", + "chat.bsky.group.listMutualGroups", + "chat.bsky.group.rejectJoinRequest", + "chat.bsky.group.removeMembers", + "chat.bsky.group.requestJoin", + "chat.bsky.group.withdrawJoinRequest" + ] + }, + { + "type": "permission", + "resource": "repo", + "action": ["create", "update", "delete"], + "collection": ["chat.bsky.actor.declaration"] + } + ] + } + } +} diff --git a/lexicons/chat/bsky/convo/acceptConvo.json b/lexicons/chat/bsky/convo/acceptConvo.json new file mode 100644 index 0000000000..ea87018943 --- /dev/null +++ b/lexicons/chat/bsky/convo/acceptConvo.json @@ -0,0 +1,39 @@ +{ + "lexicon": 1, + "id": "chat.bsky.convo.acceptConvo", + "defs": { + "main": { + "type": "procedure", + "description": "Marks a conversation as accepted, so it is shown in the list of accepted convos instead on the request convos.", + "errors": [ + { + "name": "InvalidConvo" + } + ], + "input": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["convoId"], + "properties": { + "convoId": { + "type": "string" + } + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "properties": { + "rev": { + "description": "Rev when the convo was accepted. If not present, the convo was already accepted.", + "type": "string" + } + } + } + } + } + } +} diff --git a/lexicons/chat/bsky/convo/addReaction.json b/lexicons/chat/bsky/convo/addReaction.json new file mode 100644 index 0000000000..c34b0c30f6 --- /dev/null +++ b/lexicons/chat/bsky/convo/addReaction.json @@ -0,0 +1,66 @@ +{ + "lexicon": 1, + "id": "chat.bsky.convo.addReaction", + "defs": { + "main": { + "type": "procedure", + "description": "Adds an emoji reaction to a message. Requires authentication. It is idempotent, so multiple calls from the same user with the same emoji result in a single reaction.", + "input": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["convoId", "messageId", "value"], + "properties": { + "convoId": { + "type": "string" + }, + "messageId": { + "type": "string" + }, + "value": { + "type": "string", + "minLength": 1, + "maxLength": 64, + "minGraphemes": 1, + "maxGraphemes": 1 + } + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["message"], + "properties": { + "message": { + "type": "ref", + "ref": "chat.bsky.convo.defs#messageView" + } + } + } + }, + "errors": [ + { + "name": "InvalidConvo" + }, + { + "name": "ReactionNotAllowed", + "description": "Indicates that reactions are not allowed on this message, e.g. because it is a system message." + }, + { + "name": "ReactionMessageDeleted", + "description": "Indicates that the message has been deleted and reactions can no longer be added/removed." + }, + { + "name": "ReactionLimitReached", + "description": "Indicates that the message has the maximum number of reactions allowed for a single user, and the requested reaction wasn't yet present. If it was already present, the request will not fail since it is idempotent." + }, + { + "name": "ReactionInvalidValue", + "description": "Indicates the value for the reaction is not acceptable. In general, this means it is not an emoji." + } + ] + } + } +} diff --git a/lexicons/chat/bsky/convo/defs.json b/lexicons/chat/bsky/convo/defs.json new file mode 100644 index 0000000000..bd0ed778b6 --- /dev/null +++ b/lexicons/chat/bsky/convo/defs.json @@ -0,0 +1,1084 @@ +{ + "lexicon": 1, + "id": "chat.bsky.convo.defs", + "defs": { + "convoKind": { + "type": "string", + "knownValues": ["direct", "group"] + }, + "convoLockStatus": { + "type": "string", + "knownValues": ["unlocked", "locked", "locked-permanently"] + }, + "convoStatus": { + "type": "string", + "knownValues": ["request", "accepted"] + }, + "convoRef": { + "type": "object", + "required": ["did", "convoId"], + "properties": { + "did": { + "type": "string", + "format": "did" + }, + "convoId": { + "type": "string" + } + } + }, + "messageRef": { + "type": "object", + "required": ["did", "messageId", "convoId"], + "properties": { + "did": { + "type": "string", + "format": "did" + }, + "convoId": { + "type": "string" + }, + "messageId": { + "type": "string" + } + } + }, + "messageInput": { + "type": "object", + "required": ["text"], + "properties": { + "text": { + "type": "string", + "maxLength": 10000, + "maxGraphemes": 1000 + }, + "facets": { + "type": "array", + "description": "Annotations of text (mentions, URLs, hashtags, etc)", + "items": { + "type": "ref", + "ref": "app.bsky.richtext.facet" + } + }, + "embed": { + "type": "union", + "refs": ["app.bsky.embed.record", "chat.bsky.embed.joinLink"] + }, + "replyTo": { + "description": "If set, the message this message is replying to. The referenced message must be in the same convo.", + "type": "ref", + "ref": "#replyRef" + } + } + }, + "replyRef": { + "description": "A reference to another message within the same convo, used to indicate that a message is a reply to it.", + "type": "object", + "required": ["messageId"], + "properties": { + "messageId": { + "type": "string" + } + } + }, + "messageView": { + "type": "object", + "required": ["id", "rev", "text", "sender", "sentAt"], + "properties": { + "id": { + "type": "string" + }, + "rev": { + "type": "string" + }, + "text": { + "type": "string", + "maxLength": 10000, + "maxGraphemes": 1000 + }, + "facets": { + "type": "array", + "description": "Annotations of text (mentions, URLs, hashtags, etc)", + "items": { + "type": "ref", + "ref": "app.bsky.richtext.facet" + } + }, + "embed": { + "type": "union", + "refs": [ + "app.bsky.embed.record#view", + "chat.bsky.embed.joinLink#view" + ] + }, + "reactions": { + "type": "array", + "description": "Reactions to this message, in ascending order of creation time.", + "items": { + "type": "ref", + "ref": "#reactionView" + } + }, + "replyTo": { + "description": "If set, the message this message is replying to. The full view of the referenced message is embedded so the client can render it inline. Only a single level is embedded: the embedded message will not itself have a populated 'replyTo' field even if it was also a reply.", + "type": "union", + "refs": [ + "#messageView", + "#deletedMessageView", + "#messageBeforeUserJoinedGroupView" + ] + }, + "sender": { + "type": "ref", + "ref": "#messageViewSender" + }, + "sentAt": { + "type": "string", + "format": "datetime" + } + } + }, + "systemMessageReferredUser": { + "type": "object", + "required": ["did"], + "properties": { + "did": { + "type": "string", + "format": "did" + } + } + }, + "systemMessageView": { + "type": "object", + "required": ["id", "rev", "sentAt", "data"], + "properties": { + "id": { + "type": "string" + }, + "rev": { + "type": "string" + }, + "sentAt": { + "type": "string", + "format": "datetime" + }, + "data": { + "type": "union", + "refs": [ + "#systemMessageDataAddMember", + "#systemMessageDataRemoveMember", + "#systemMessageDataMemberJoin", + "#systemMessageDataMemberLeave", + "#systemMessageDataLockConvo", + "#systemMessageDataUnlockConvo", + "#systemMessageDataLockConvoPermanently", + "#systemMessageDataEditGroup", + "#systemMessageDataCreateJoinLink", + "#systemMessageDataEditJoinLink", + "#systemMessageDataEnableJoinLink", + "#systemMessageDataDisableJoinLink" + ] + } + } + }, + "systemMessageDataAddMember": { + "description": "System message indicating a user was added to the group convo.", + "type": "object", + "required": ["member", "role", "addedBy"], + "properties": { + "member": { + "description": "Current view of the member who was added.", + "type": "ref", + "ref": "#systemMessageReferredUser" + }, + "role": { + "description": "Role the user was added to the group with. The role from 'member' will reflect the current data, not historical.", + "type": "ref", + "ref": "chat.bsky.actor.defs#memberRole" + }, + "addedBy": { + "type": "ref", + "ref": "#systemMessageReferredUser" + } + } + }, + "systemMessageDataRemoveMember": { + "description": "System message indicating a user was removed from the group convo.", + "type": "object", + "required": ["member", "removedBy"], + "properties": { + "member": { + "description": "Current view of the member who was removed.", + "type": "ref", + "ref": "#systemMessageReferredUser" + }, + "removedBy": { + "type": "ref", + "ref": "#systemMessageReferredUser" + } + } + }, + "systemMessageDataMemberJoin": { + "description": "System message indicating a user joined the group convo via join link.", + "type": "object", + "required": ["member", "role"], + "properties": { + "member": { + "description": "Current view of the member who joined.", + "type": "ref", + "ref": "#systemMessageReferredUser" + }, + "role": { + "description": "Role the user was added to the group with. The role from 'member' will reflect the current data, not historical.", + "type": "ref", + "ref": "chat.bsky.actor.defs#memberRole" + }, + "approvedBy": { + "description": "If join link was configured to require approval, this will be set to who approved the request. Undefined if approval was not required.", + "type": "ref", + "ref": "#systemMessageReferredUser" + } + } + }, + "systemMessageDataMemberLeave": { + "description": "System message indicating a user voluntarily left the group convo.", + "type": "object", + "required": ["member"], + "properties": { + "member": { + "description": "Current view of the member who left the group.", + "type": "ref", + "ref": "#systemMessageReferredUser" + } + } + }, + "systemMessageDataLockConvo": { + "description": "System message indicating the group convo was locked.", + "type": "object", + "required": ["lockedBy"], + "properties": { + "lockedBy": { + "description": "Current view of the member who locked the group.", + "type": "ref", + "ref": "#systemMessageReferredUser" + } + } + }, + "systemMessageDataUnlockConvo": { + "description": "System message indicating the group convo was unlocked.", + "type": "object", + "required": ["unlockedBy"], + "properties": { + "unlockedBy": { + "description": "Current view of the member who unlocked the group.", + "type": "ref", + "ref": "#systemMessageReferredUser" + } + } + }, + "systemMessageDataLockConvoPermanently": { + "description": "System message indicating the group convo was locked permanently.", + "type": "object", + "required": ["lockedBy"], + "properties": { + "lockedBy": { + "description": "Current view of the member who locked the group.", + "type": "ref", + "ref": "#systemMessageReferredUser" + } + } + }, + "systemMessageDataEditGroup": { + "description": "System message indicating the group info was edited.", + "type": "object", + "properties": { + "oldName": { + "description": "Group name that was replaced.", + "type": "string" + }, + "newName": { + "description": "Group name that replaced the old.", + "type": "string" + } + } + }, + "systemMessageDataCreateJoinLink": { + "description": "System message indicating the group join link was created.", + "type": "object", + "properties": {} + }, + "systemMessageDataEditJoinLink": { + "description": "System message indicating the group join link was edited.", + "type": "object", + "properties": {} + }, + "systemMessageDataEnableJoinLink": { + "description": "System message indicating the group join link was enabled.", + "type": "object", + "properties": {} + }, + "systemMessageDataDisableJoinLink": { + "description": "System message indicating the group join link was disabled.", + "type": "object", + "properties": {} + }, + "deletedMessageView": { + "type": "object", + "required": ["id", "rev", "sender", "sentAt"], + "properties": { + "id": { + "type": "string" + }, + "rev": { + "type": "string" + }, + "sender": { + "type": "ref", + "ref": "#messageViewSender" + }, + "sentAt": { + "type": "string", + "format": "datetime" + } + } + }, + "messageBeforeUserJoinedGroupView": { + "description": "Placeholder embedded in place of a reply's parent message when that parent was sent before the viewer joined the group convo. The viewer has no access to that history, so no message data is carried.", + "type": "object", + "properties": {} + }, + "messageViewSender": { + "type": "object", + "required": ["did"], + "properties": { + "did": { + "type": "string", + "format": "did" + } + } + }, + "reactionView": { + "type": "object", + "required": ["value", "sender", "createdAt"], + "properties": { + "value": { + "type": "string" + }, + "sender": { + "type": "ref", + "ref": "#reactionViewSender" + }, + "createdAt": { + "type": "string", + "format": "datetime" + } + } + }, + "reactionViewSender": { + "type": "object", + "required": ["did"], + "properties": { + "did": { + "type": "string", + "format": "did" + } + } + }, + "messageAndReactionView": { + "type": "object", + "required": ["message", "reaction"], + "properties": { + "message": { + "type": "ref", + "ref": "#messageView" + }, + "reaction": { + "type": "ref", + "ref": "#reactionView" + } + } + }, + "convoView": { + "type": "object", + "required": ["id", "rev", "members", "muted", "unreadCount"], + "properties": { + "id": { + "type": "string" + }, + "rev": { + "type": "string" + }, + "members": { + "description": "Members of this conversation. For direct convos, it will be an immutable list of the 2 members. For group convos, it will a list of important members (the first few members, the viewer, the member who added the viewer, the member who sent the last message, the member who sent the last reaction), but will not contain the full list of members. Use chat.bsky.convo.getConvoMembers to list all members.", + "type": "array", + "items": { + "type": "ref", + "ref": "chat.bsky.actor.defs#profileViewBasic" + } + }, + "lastMessage": { + "type": "union", + "refs": ["#messageView", "#deletedMessageView", "#systemMessageView"] + }, + "lastReaction": { + "type": "union", + "refs": ["#messageAndReactionView"] + }, + "muted": { + "type": "boolean" + }, + "status": { + "description": "Convo status for the viewer member (not the convo itself).", + "type": "ref", + "ref": "#convoStatus" + }, + "unreadCount": { + "type": "integer" + }, + "kind": { + "description": "Union field that has data specific to different kinds of convos.", + "type": "union", + "refs": ["#directConvo", "#groupConvo"] + } + } + }, + "directConvo": { + "type": "object", + "properties": {} + }, + "groupConvo": { + "type": "object", + "required": [ + "createdAt", + "lockStatus", + "lockStatusModerationOverride", + "memberCount", + "memberLimit", + "name" + ], + "properties": { + "createdAt": { + "type": "string", + "format": "datetime" + }, + "joinLink": { + "type": "ref", + "ref": "chat.bsky.group.defs#joinLinkView" + }, + "joinRequestCount": { + "type": "integer", + "description": "The total number of pending join requests for the group conversation. Only present for the owner. Capped at 21." + }, + "lockStatus": { + "description": "The lock status of the conversation.", + "type": "ref", + "ref": "#convoLockStatus" + }, + "lockStatusModerationOverride": { + "description": "Whether the lock status is being forced by a moderation override (account inactivation or convo takedown) rather than the owner's own setting.", + "type": "boolean" + }, + "memberCount": { + "type": "integer", + "description": "The total number of members in the group conversation." + }, + "memberLimit": { + "type": "integer", + "description": "The maximum number of members allowed in the group conversation." + }, + "name": { + "type": "string", + "description": "The display name of the group conversation.", + "maxGraphemes": 50, + "maxLength": 500 + }, + "unreadJoinRequestCount": { + "type": "integer", + "description": "The number of unread join requests for the group conversation. Only present for the owner." + } + } + }, + "logBeginConvo": { + "description": "Event indicating a convo containing the viewer was started. Can be direct or group. When a member is added to a group convo, they also get this event.", + "type": "object", + "required": ["rev", "convoId"], + "properties": { + "rev": { + "type": "string" + }, + "convoId": { + "type": "string" + } + } + }, + "logAcceptConvo": { + "description": "Event indicating the viewer accepted a convo, and it can be moved out of the request inbox. Can be direct or group.", + "type": "object", + "required": ["rev", "convoId"], + "properties": { + "rev": { + "type": "string" + }, + "convoId": { + "type": "string" + } + } + }, + "logLeaveConvo": { + "description": "Event indicating the viewer left a convo. Can be direct or group.", + "type": "object", + "required": ["rev", "convoId"], + "properties": { + "rev": { + "type": "string" + }, + "convoId": { + "type": "string" + } + } + }, + "logMuteConvo": { + "description": "Event indicating the viewer muted a convo. Can be direct or group.", + "type": "object", + "required": ["rev", "convoId"], + "properties": { + "rev": { + "type": "string" + }, + "convoId": { + "type": "string" + } + } + }, + "logUnmuteConvo": { + "description": "Event indicating the viewer unmuted a convo. Can be direct or group.", + "type": "object", + "required": ["rev", "convoId"], + "properties": { + "rev": { + "type": "string" + }, + "convoId": { + "type": "string" + } + } + }, + "logCreateMessage": { + "description": "Event indicating a user-originated message was created. Is not emitted for system messages.", + "type": "object", + "required": ["rev", "convoId", "message"], + "properties": { + "rev": { + "type": "string" + }, + "convoId": { + "type": "string" + }, + "message": { + "type": "union", + "refs": ["#messageView", "#deletedMessageView"] + }, + "relatedProfiles": { + "description": "Profiles referred to in the message view. This isn't required for compatibility, because it was added later, but should generally be present.", + "type": "array", + "items": { + "type": "ref", + "ref": "chat.bsky.actor.defs#profileViewBasic" + } + } + } + }, + "logDeleteMessage": { + "description": "Event indicating a user-originated message was deleted. Is not emitted for system messages.", + "type": "object", + "required": ["rev", "convoId", "message"], + "properties": { + "rev": { + "type": "string" + }, + "convoId": { + "type": "string" + }, + "message": { + "type": "union", + "refs": ["#messageView", "#deletedMessageView"] + } + } + }, + "logReadMessage": { + "description": "DEPRECATED: use logReadConvo instead. Event indicating a convo was read up to a certain message.", + "type": "object", + "required": ["rev", "convoId", "message"], + "properties": { + "rev": { + "type": "string" + }, + "convoId": { + "type": "string" + }, + "message": { + "type": "union", + "refs": ["#messageView", "#deletedMessageView", "#systemMessageView"] + } + } + }, + "logAddReaction": { + "description": "Event indicating a reaction was added to a message.", + "type": "object", + "required": ["rev", "convoId", "message", "reaction"], + "properties": { + "rev": { + "type": "string" + }, + "convoId": { + "type": "string" + }, + "message": { + "type": "union", + "refs": ["#messageView", "#deletedMessageView"] + }, + "reaction": { + "type": "ref", + "ref": "#reactionView" + }, + "relatedProfiles": { + "description": "Profiles referred in the message and reaction views. This isn't required for compatibility, because it was added later, but should generally be present.", + "type": "array", + "items": { + "type": "ref", + "ref": "chat.bsky.actor.defs#profileViewBasic" + } + } + } + }, + "logRemoveReaction": { + "description": "Event indicating a reaction was removed from a message.", + "type": "object", + "required": ["rev", "convoId", "message", "reaction"], + "properties": { + "rev": { + "type": "string" + }, + "convoId": { + "type": "string" + }, + "message": { + "type": "union", + "refs": ["#messageView", "#deletedMessageView"] + }, + "reaction": { + "type": "ref", + "ref": "#reactionView" + }, + "relatedProfiles": { + "description": "Profiles referred in the message and reaction views. This isn't required for compatibility, because it was added later, but should generally be present.", + "type": "array", + "items": { + "type": "ref", + "ref": "chat.bsky.actor.defs#profileViewBasic" + } + } + } + }, + "logReadConvo": { + "description": "Event indicating a convo was read up to a certain message.", + "type": "object", + "required": ["rev", "convoId", "message"], + "properties": { + "rev": { + "type": "string" + }, + "convoId": { + "type": "string" + }, + "message": { + "type": "union", + "refs": ["#messageView", "#deletedMessageView", "#systemMessageView"] + } + } + }, + "logAddMember": { + "description": "Event indicating a member was added to a group convo. The member who was added gets a logBeginConvo (to create the convo) but also a logAddMember (to show the system message as the first message the user sees).", + "type": "object", + "required": ["rev", "convoId", "message", "relatedProfiles"], + "properties": { + "rev": { + "type": "string" + }, + "convoId": { + "type": "string" + }, + "message": { + "description": "A system message with data of type #systemMessageDataAddMember", + "type": "ref", + "ref": "#systemMessageView" + }, + "relatedProfiles": { + "description": "Profiles referred in the system message.", + "type": "array", + "items": { + "type": "ref", + "ref": "chat.bsky.actor.defs#profileViewBasic" + } + } + } + }, + "logRemoveMember": { + "description": "Event indicating a member was removed from a group convo. The member who was removed gets a logLeaveConvo (to leave the convo) but not a logRemoveMember (because they already left, so can't see the system message).", + "type": "object", + "required": ["rev", "convoId", "message", "relatedProfiles"], + "properties": { + "rev": { + "type": "string" + }, + "convoId": { + "type": "string" + }, + "message": { + "description": "A system message with data of type #systemMessageDataRemoveMember", + "type": "ref", + "ref": "#systemMessageView" + }, + "relatedProfiles": { + "description": "Profiles referred in the system message.", + "type": "array", + "items": { + "type": "ref", + "ref": "chat.bsky.actor.defs#profileViewBasic" + } + } + } + }, + "logMemberJoin": { + "description": "Event indicating a member joined a group convo via join link. The member who was added gets a logBeginConvo (to create the convo) but also a logMemberJoin (to show the system message as the first message the user sees).", + "type": "object", + "required": ["rev", "convoId", "message", "relatedProfiles"], + "properties": { + "rev": { + "type": "string" + }, + "convoId": { + "type": "string" + }, + "message": { + "description": "A system message with data of type #systemMessageDataMemberJoin", + "type": "ref", + "ref": "#systemMessageView" + }, + "relatedProfiles": { + "description": "Profiles referred in the system message.", + "type": "array", + "items": { + "type": "ref", + "ref": "chat.bsky.actor.defs#profileViewBasic" + } + } + } + }, + "logMemberLeave": { + "description": "Event indicating a member voluntarily left a group convo. The member who was removed gets a logLeaveConvo (to leave the convo) but not a logMemberLeave (because they already left, so can't see the system message).", + "type": "object", + "required": ["rev", "convoId", "message", "relatedProfiles"], + "properties": { + "rev": { + "type": "string" + }, + "convoId": { + "type": "string" + }, + "message": { + "description": "A system message with data of type #systemMessageDataMemberLeave", + "type": "ref", + "ref": "#systemMessageView" + }, + "relatedProfiles": { + "description": "Profiles referred in the system message.", + "type": "array", + "items": { + "type": "ref", + "ref": "chat.bsky.actor.defs#profileViewBasic" + } + } + } + }, + "logLockConvo": { + "description": "Event indicating a group convo was locked.", + "type": "object", + "required": ["rev", "convoId", "message", "relatedProfiles"], + "properties": { + "rev": { + "type": "string" + }, + "convoId": { + "type": "string" + }, + "message": { + "description": "A system message with data of type #systemMessageDataLockConvo", + "type": "ref", + "ref": "#systemMessageView" + }, + "relatedProfiles": { + "description": "Profiles referred in the system message.", + "type": "array", + "items": { + "type": "ref", + "ref": "chat.bsky.actor.defs#profileViewBasic" + } + } + } + }, + "logUnlockConvo": { + "description": "Event indicating a group convo was unlocked.", + "type": "object", + "required": ["rev", "convoId", "message", "relatedProfiles"], + "properties": { + "rev": { + "type": "string" + }, + "convoId": { + "type": "string" + }, + "message": { + "description": "A system message with data of type #systemMessageDataUnlockConvo", + "type": "ref", + "ref": "#systemMessageView" + }, + "relatedProfiles": { + "description": "Profiles referred in the system message.", + "type": "array", + "items": { + "type": "ref", + "ref": "chat.bsky.actor.defs#profileViewBasic" + } + } + } + }, + "logLockConvoPermanently": { + "description": "Event indicating a group convo was locked permanently.", + "type": "object", + "required": ["rev", "convoId", "message", "relatedProfiles"], + "properties": { + "rev": { + "type": "string" + }, + "convoId": { + "type": "string" + }, + "message": { + "description": "A system message with data of type #systemMessageDataLockConvoPermanently", + "type": "ref", + "ref": "#systemMessageView" + }, + "relatedProfiles": { + "description": "Profiles referred in the system message.", + "type": "array", + "items": { + "type": "ref", + "ref": "chat.bsky.actor.defs#profileViewBasic" + } + } + } + }, + "logEditGroup": { + "description": "Event indicating info about group convo was edited.", + "type": "object", + "required": ["rev", "convoId", "message"], + "properties": { + "rev": { + "type": "string" + }, + "convoId": { + "type": "string" + }, + "message": { + "description": "A system message with data of type #systemMessageDataEditGroup", + "type": "ref", + "ref": "#systemMessageView" + } + } + }, + "logCreateJoinLink": { + "description": "Event indicating a join link was created for a group convo.", + "type": "object", + "required": ["rev", "convoId", "message"], + "properties": { + "rev": { + "type": "string" + }, + "convoId": { + "type": "string" + }, + "message": { + "description": "A system message with data of type #systemMessageDataCreateJoinLink", + "type": "ref", + "ref": "#systemMessageView" + } + } + }, + "logEditJoinLink": { + "description": "Event indicating a settings about a join link for a group convo were edited.", + "type": "object", + "required": ["rev", "convoId", "message"], + "properties": { + "rev": { + "type": "string" + }, + "convoId": { + "type": "string" + }, + "message": { + "description": "A system message with data of type #systemMessageDataEditJoinLink", + "type": "ref", + "ref": "#systemMessageView" + } + } + }, + "logEnableJoinLink": { + "description": "Event indicating a join link was enabled for a group convo.", + "type": "object", + "required": ["rev", "convoId", "message"], + "properties": { + "rev": { + "type": "string" + }, + "convoId": { + "type": "string" + }, + "message": { + "description": "A system message with data of type #systemMessageDataEnableJoinLink", + "type": "ref", + "ref": "#systemMessageView" + } + } + }, + "logDisableJoinLink": { + "description": "Event indicating a join link was disabled for a group convo.", + "type": "object", + "required": ["rev", "convoId", "message"], + "properties": { + "rev": { + "type": "string" + }, + "convoId": { + "type": "string" + }, + "message": { + "description": "A system message with data of type #systemMessageDataDisableJoinLink", + "type": "ref", + "ref": "#systemMessageView" + } + } + }, + "logIncomingJoinRequest": { + "description": "Event indicating a join request was made to a group the viewer owns. Only the owner gets this.", + "type": "object", + "required": ["rev", "convoId", "member"], + "properties": { + "rev": { + "type": "string" + }, + "convoId": { + "type": "string" + }, + "member": { + "description": "Prospective member who requested to join.", + "type": "ref", + "ref": "chat.bsky.actor.defs#profileViewBasic" + } + } + }, + "logApproveJoinRequest": { + "description": "Event indicating a join request was approved by the viewer. Only the owner gets this. The approved member gets a logBeginConvo.", + "type": "object", + "required": ["rev", "convoId", "member"], + "properties": { + "rev": { + "type": "string" + }, + "convoId": { + "type": "string" + }, + "member": { + "description": "Prospective member who requested to join.", + "type": "ref", + "ref": "chat.bsky.actor.defs#profileViewBasic" + } + } + }, + "logRejectJoinRequest": { + "description": "Event indicating a join request was rejected by the viewer. Only the owner gets this.", + "type": "object", + "required": ["rev", "convoId", "member"], + "properties": { + "rev": { + "type": "string" + }, + "convoId": { + "type": "string" + }, + "member": { + "description": "Prospective member who requested to join.", + "type": "ref", + "ref": "chat.bsky.actor.defs#profileViewBasic" + } + } + }, + "logOutgoingJoinRequest": { + "description": "Event indicating a join request was made by the requester. Only requester actor gets this.", + "type": "object", + "required": ["rev", "convoId"], + "properties": { + "rev": { + "type": "string" + }, + "convoId": { + "type": "string" + } + } + }, + "logWithdrawIncomingJoinRequest": { + "description": "Event indicating a prospective member withdrew their join request. Only the owner gets this.", + "type": "object", + "required": ["rev", "convoId", "member"], + "properties": { + "rev": { + "type": "string" + }, + "convoId": { + "type": "string" + }, + "member": { + "description": "Prospective member who withdrew their join request.", + "type": "ref", + "ref": "chat.bsky.actor.defs#profileViewBasic" + } + } + }, + "logWithdrawOutgoingJoinRequest": { + "description": "Event indicating the viewer withdrew their own join request. Only requester actor gets this.", + "type": "object", + "required": ["rev", "convoId"], + "properties": { + "rev": { + "type": "string" + }, + "convoId": { + "type": "string" + } + } + }, + "logReadJoinRequests": { + "description": "Event indicating the group owner marked join requests as read. Only the owner gets this.", + "type": "object", + "required": ["rev", "convoId"], + "properties": { + "rev": { + "type": "string" + }, + "convoId": { + "type": "string" + } + } + } + } +} diff --git a/lexicons/chat/bsky/convo/deleteMessageForSelf.json b/lexicons/chat/bsky/convo/deleteMessageForSelf.json new file mode 100644 index 0000000000..5a275c32a4 --- /dev/null +++ b/lexicons/chat/bsky/convo/deleteMessageForSelf.json @@ -0,0 +1,41 @@ +{ + "lexicon": 1, + "id": "chat.bsky.convo.deleteMessageForSelf", + "defs": { + "main": { + "type": "procedure", + "description": "Marks a message as deleted for the viewer, so they won't see that message in future enumerations.", + "errors": [ + { + "name": "InvalidConvo" + }, + { + "name": "MessageDeleteNotAllowed", + "description": "Indicates that this message cannot be deleted, e.g. because it is a system message." + } + ], + "input": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["convoId", "messageId"], + "properties": { + "convoId": { + "type": "string" + }, + "messageId": { + "type": "string" + } + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "ref", + "ref": "chat.bsky.convo.defs#deletedMessageView" + } + } + } + } +} diff --git a/lexicons/chat/bsky/convo/exportAccountData.json b/lexicons/chat/bsky/convo/exportAccountData.json new file mode 100644 index 0000000000..4c2067a975 --- /dev/null +++ b/lexicons/chat/bsky/convo/exportAccountData.json @@ -0,0 +1,13 @@ +{ + "lexicon": 1, + "id": "chat.bsky.convo.exportAccountData", + "description": "Stub: chat.bsky.convo.exportAccountData is referenced in chat.bsky.authFullChatClient but the lexicon may have been renamed in the local repo.", + "defs": { + "main": { + "type": "query", + "output": { + "encoding": "application/jsonl" + } + } + } +} diff --git a/lexicons/chat/bsky/convo/getConvo.json b/lexicons/chat/bsky/convo/getConvo.json new file mode 100644 index 0000000000..43ef2569b2 --- /dev/null +++ b/lexicons/chat/bsky/convo/getConvo.json @@ -0,0 +1,37 @@ +{ + "lexicon": 1, + "id": "chat.bsky.convo.getConvo", + "defs": { + "main": { + "type": "query", + "description": "Gets an existing conversation by its ID.", + "errors": [ + { + "name": "InvalidConvo" + } + ], + "parameters": { + "type": "params", + "required": ["convoId"], + "properties": { + "convoId": { + "type": "string" + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["convo"], + "properties": { + "convo": { + "type": "ref", + "ref": "chat.bsky.convo.defs#convoView" + } + } + } + } + } + } +} diff --git a/lexicons/chat/bsky/convo/getConvoAvailability.json b/lexicons/chat/bsky/convo/getConvoAvailability.json new file mode 100644 index 0000000000..073e8998a9 --- /dev/null +++ b/lexicons/chat/bsky/convo/getConvoAvailability.json @@ -0,0 +1,41 @@ +{ + "lexicon": 1, + "id": "chat.bsky.convo.getConvoAvailability", + "defs": { + "main": { + "type": "query", + "description": "Check whether the requester and the other members can start a 1-1 chat. Only applicable to direct (non-group) conversations. If an existing convo is found for these members, it is returned. Does not create a new convo if it doesn't exist.", + "parameters": { + "type": "params", + "required": ["members"], + "properties": { + "members": { + "type": "array", + "minLength": 1, + "maxLength": 10, + "items": { + "type": "string", + "format": "did" + } + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["canChat"], + "properties": { + "canChat": { + "type": "boolean" + }, + "convo": { + "type": "ref", + "ref": "chat.bsky.convo.defs#convoView" + } + } + } + } + } + } +} diff --git a/lexicons/chat/bsky/convo/getConvoForMembers.json b/lexicons/chat/bsky/convo/getConvoForMembers.json new file mode 100644 index 0000000000..b2f8d63cac --- /dev/null +++ b/lexicons/chat/bsky/convo/getConvoForMembers.json @@ -0,0 +1,58 @@ +{ + "lexicon": 1, + "id": "chat.bsky.convo.getConvoForMembers", + "defs": { + "main": { + "type": "query", + "description": "Get or create a 1-1 conversation for the given members. Always returns the same direct (non-group) conversation. To create a group conversation, use createGroup.", + "errors": [ + { + "name": "AccountSuspended" + }, + { + "name": "BlockedActor" + }, + { + "name": "BlockedSubject" + }, + { + "name": "MessagesDisabled" + }, + { + "name": "NotFollowedBySender" + }, + { + "name": "RecipientNotFound" + } + ], + "parameters": { + "type": "params", + "required": ["members"], + "properties": { + "members": { + "type": "array", + "minLength": 1, + "maxLength": 10, + "items": { + "type": "string", + "format": "did" + } + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["convo"], + "properties": { + "convo": { + "type": "ref", + "ref": "chat.bsky.convo.defs#convoView" + } + } + } + } + } + } +} diff --git a/lexicons/chat/bsky/convo/getConvoMembers.json b/lexicons/chat/bsky/convo/getConvoMembers.json new file mode 100644 index 0000000000..80388c598f --- /dev/null +++ b/lexicons/chat/bsky/convo/getConvoMembers.json @@ -0,0 +1,52 @@ +{ + "lexicon": 1, + "id": "chat.bsky.convo.getConvoMembers", + "defs": { + "main": { + "type": "query", + "description": "Returns a paginated list of members from a conversation.", + "errors": [ + { + "name": "InvalidConvo" + } + ], + "parameters": { + "type": "params", + "required": ["convoId"], + "properties": { + "convoId": { + "type": "string" + }, + "limit": { + "type": "integer", + "minimum": 1, + "maximum": 100, + "default": 50 + }, + "cursor": { + "type": "string" + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["members"], + "properties": { + "cursor": { + "type": "string" + }, + "members": { + "type": "array", + "items": { + "type": "ref", + "ref": "chat.bsky.actor.defs#profileViewBasic" + } + } + } + } + } + } + } +} diff --git a/lexicons/chat/bsky/convo/getLog.json b/lexicons/chat/bsky/convo/getLog.json new file mode 100644 index 0000000000..7ce0e51c68 --- /dev/null +++ b/lexicons/chat/bsky/convo/getLog.json @@ -0,0 +1,68 @@ +{ + "lexicon": 1, + "id": "chat.bsky.convo.getLog", + "defs": { + "main": { + "type": "query", + "parameters": { + "type": "params", + "required": [], + "properties": { + "cursor": { + "type": "string" + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["logs"], + "properties": { + "cursor": { + "type": "string" + }, + "logs": { + "type": "array", + "items": { + "type": "union", + "refs": [ + "chat.bsky.convo.defs#logBeginConvo", + "chat.bsky.convo.defs#logAcceptConvo", + "chat.bsky.convo.defs#logLeaveConvo", + "chat.bsky.convo.defs#logMuteConvo", + "chat.bsky.convo.defs#logUnmuteConvo", + "chat.bsky.convo.defs#logCreateMessage", + "chat.bsky.convo.defs#logDeleteMessage", + "chat.bsky.convo.defs#logReadMessage", + "chat.bsky.convo.defs#logAddReaction", + "chat.bsky.convo.defs#logRemoveReaction", + "chat.bsky.convo.defs#logReadConvo", + "chat.bsky.convo.defs#logAddMember", + "chat.bsky.convo.defs#logRemoveMember", + "chat.bsky.convo.defs#logMemberJoin", + "chat.bsky.convo.defs#logMemberLeave", + "chat.bsky.convo.defs#logLockConvo", + "chat.bsky.convo.defs#logUnlockConvo", + "chat.bsky.convo.defs#logLockConvoPermanently", + "chat.bsky.convo.defs#logEditGroup", + "chat.bsky.convo.defs#logCreateJoinLink", + "chat.bsky.convo.defs#logEditJoinLink", + "chat.bsky.convo.defs#logEnableJoinLink", + "chat.bsky.convo.defs#logDisableJoinLink", + "chat.bsky.convo.defs#logIncomingJoinRequest", + "chat.bsky.convo.defs#logApproveJoinRequest", + "chat.bsky.convo.defs#logRejectJoinRequest", + "chat.bsky.convo.defs#logOutgoingJoinRequest", + "chat.bsky.convo.defs#logWithdrawIncomingJoinRequest", + "chat.bsky.convo.defs#logWithdrawOutgoingJoinRequest", + "chat.bsky.convo.defs#logReadJoinRequests" + ] + } + } + } + } + } + } + } +} diff --git a/lexicons/chat/bsky/convo/getMessages.json b/lexicons/chat/bsky/convo/getMessages.json new file mode 100644 index 0000000000..f70d4597aa --- /dev/null +++ b/lexicons/chat/bsky/convo/getMessages.json @@ -0,0 +1,64 @@ +{ + "lexicon": 1, + "id": "chat.bsky.convo.getMessages", + "defs": { + "main": { + "type": "query", + "description": "Returns a page of messages from a conversation.", + "errors": [ + { + "name": "InvalidConvo" + } + ], + "parameters": { + "type": "params", + "required": ["convoId"], + "properties": { + "convoId": { + "type": "string" + }, + "limit": { + "type": "integer", + "minimum": 1, + "maximum": 100, + "default": 50 + }, + "cursor": { + "type": "string" + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["messages"], + "properties": { + "cursor": { + "type": "string" + }, + "messages": { + "type": "array", + "items": { + "type": "union", + "refs": [ + "chat.bsky.convo.defs#messageView", + "chat.bsky.convo.defs#deletedMessageView", + "chat.bsky.convo.defs#systemMessageView" + ] + } + }, + "relatedProfiles": { + "description": "Set of all members who authored or reacted to the returned messages. Members referred to by system messages are also included.", + "type": "array", + "items": { + "type": "ref", + "ref": "chat.bsky.actor.defs#profileViewBasic" + } + } + } + } + } + } + } +} diff --git a/lexicons/chat/bsky/convo/getUnreadCounts.json b/lexicons/chat/bsky/convo/getUnreadCounts.json new file mode 100644 index 0000000000..c0916454d4 --- /dev/null +++ b/lexicons/chat/bsky/convo/getUnreadCounts.json @@ -0,0 +1,37 @@ +{ + "lexicon": 1, + "id": "chat.bsky.convo.getUnreadCounts", + "defs": { + "main": { + "type": "query", + "description": "Returns unread conversation counts for conversations that are unlocked, not muted, split by convo status. Direct convos are excluded when a block relationship exists between the actor and the other member, or when the other member's account is deleted or deactivated. Group convos are considered unread if they have unread join request counts.", + "parameters": { + "type": "params", + "properties": { + "includeGroupChats": { + "type": "boolean", + "default": true, + "description": "When false, group convos are excluded from the counts." + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["unreadAcceptedConvos", "unreadRequestConvos"], + "properties": { + "unreadAcceptedConvos": { + "type": "integer", + "description": "Number of unread, unlocked accepted convos. Counts convos with unread messages and unread join requests. Capped at 100, where 100 means more than 99." + }, + "unreadRequestConvos": { + "type": "integer", + "description": "Number of unread, unlocked request convos. Includes convos with unread messages, but not with unread join request, since only the owner of a group has join requests to read, and the group would necessarily be accepted. Capped at 100, where 100 means more than 99." + } + } + } + } + } + } +} diff --git a/lexicons/chat/bsky/convo/leaveConvo.json b/lexicons/chat/bsky/convo/leaveConvo.json new file mode 100644 index 0000000000..d887b445bc --- /dev/null +++ b/lexicons/chat/bsky/convo/leaveConvo.json @@ -0,0 +1,46 @@ +{ + "lexicon": 1, + "id": "chat.bsky.convo.leaveConvo", + "defs": { + "main": { + "type": "procedure", + "description": "Leaves a conversation (direct or group). For group, this effectively removes membership. For direct, membership is never removed, only changed to remove from enumerations by the user who left.", + "errors": [ + { + "name": "InvalidConvo" + }, + { + "name": "OwnerCannotLeave", + "description": "The owner of a group conversation cannot leave before locking the group." + } + ], + "input": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["convoId"], + "properties": { + "convoId": { + "type": "string" + } + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["convoId", "rev"], + "properties": { + "convoId": { + "type": "string" + }, + "rev": { + "type": "string" + } + } + } + } + } + } +} diff --git a/lexicons/chat/bsky/convo/listConvoRequests.json b/lexicons/chat/bsky/convo/listConvoRequests.json new file mode 100644 index 0000000000..b006476a73 --- /dev/null +++ b/lexicons/chat/bsky/convo/listConvoRequests.json @@ -0,0 +1,46 @@ +{ + "lexicon": 1, + "id": "chat.bsky.convo.listConvoRequests", + "defs": { + "main": { + "type": "query", + "description": "Returns a page of incoming conversation requests for the user. Direct convo requests are returned as convoView; group join requests made by the user are returned as joinRequestConvoView.", + "parameters": { + "type": "params", + "properties": { + "limit": { + "type": "integer", + "minimum": 1, + "maximum": 100, + "default": 50 + }, + "cursor": { + "type": "string" + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["requests"], + "properties": { + "cursor": { + "type": "string" + }, + "requests": { + "type": "array", + "items": { + "type": "union", + "refs": [ + "chat.bsky.convo.defs#convoView", + "chat.bsky.group.defs#joinRequestConvoView" + ] + } + } + } + } + } + } + } +} diff --git a/lexicons/chat/bsky/convo/listConvos.json b/lexicons/chat/bsky/convo/listConvos.json new file mode 100644 index 0000000000..24c35dbadc --- /dev/null +++ b/lexicons/chat/bsky/convo/listConvos.json @@ -0,0 +1,62 @@ +{ + "lexicon": 1, + "id": "chat.bsky.convo.listConvos", + "defs": { + "main": { + "type": "query", + "description": "Returns a page of conversations (direct or group) for the user.", + "parameters": { + "type": "params", + "properties": { + "limit": { + "type": "integer", + "minimum": 1, + "maximum": 100, + "default": 50 + }, + "cursor": { + "type": "string" + }, + "readState": { + "type": "string", + "knownValues": ["unread"] + }, + "status": { + "description": "Filter convos by their status. It is discouraged to call with \"request\" and preferred to call chat.bsky.convo.listConvoRequests, which also includes group join requests made by the user.", + "type": "string", + "knownValues": ["request", "accepted"] + }, + "kind": { + "type": "string", + "description": "Filter by conversation kind.", + "knownValues": ["direct", "group"] + }, + "lockStatus": { + "type": "string", + "description": "Filter by conversation lock status. Values follow chat.bsky.convo.defs#convoLockStatus.", + "knownValues": ["unlocked", "locked", "locked-permanently"] + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["convos"], + "properties": { + "cursor": { + "type": "string" + }, + "convos": { + "type": "array", + "items": { + "type": "ref", + "ref": "chat.bsky.convo.defs#convoView" + } + } + } + } + } + } + } +} diff --git a/lexicons/chat/bsky/convo/lockConvo.json b/lexicons/chat/bsky/convo/lockConvo.json new file mode 100644 index 0000000000..7ef4e51d50 --- /dev/null +++ b/lexicons/chat/bsky/convo/lockConvo.json @@ -0,0 +1,46 @@ +{ + "lexicon": 1, + "id": "chat.bsky.convo.lockConvo", + "defs": { + "main": { + "type": "procedure", + "description": "Locks a group convo so no more content (messages, reactions) can be added to it.", + "errors": [ + { + "name": "ConvoLocked" + }, + { + "name": "InvalidConvo" + }, + { + "name": "InsufficientRole" + } + ], + "input": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["convoId"], + "properties": { + "convoId": { + "type": "string" + } + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["convo"], + "properties": { + "convo": { + "type": "ref", + "ref": "chat.bsky.convo.defs#convoView" + } + } + } + } + } + } +} diff --git a/lexicons/chat/bsky/convo/muteConvo.json b/lexicons/chat/bsky/convo/muteConvo.json new file mode 100644 index 0000000000..b0f3f9fe6c --- /dev/null +++ b/lexicons/chat/bsky/convo/muteConvo.json @@ -0,0 +1,40 @@ +{ + "lexicon": 1, + "id": "chat.bsky.convo.muteConvo", + "defs": { + "main": { + "type": "procedure", + "description": "Mutes a conversation, preventing notifications related to it.", + "errors": [ + { + "name": "InvalidConvo" + } + ], + "input": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["convoId"], + "properties": { + "convoId": { + "type": "string" + } + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["convo"], + "properties": { + "convo": { + "type": "ref", + "ref": "chat.bsky.convo.defs#convoView" + } + } + } + } + } + } +} diff --git a/lexicons/chat/bsky/convo/removeReaction.json b/lexicons/chat/bsky/convo/removeReaction.json new file mode 100644 index 0000000000..2c38c857cb --- /dev/null +++ b/lexicons/chat/bsky/convo/removeReaction.json @@ -0,0 +1,62 @@ +{ + "lexicon": 1, + "id": "chat.bsky.convo.removeReaction", + "defs": { + "main": { + "type": "procedure", + "description": "Removes an emoji reaction from a message. Requires authentication. It is idempotent, so multiple calls from the same user with the same emoji result in that reaction not being present, even if it already wasn't.", + "input": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["convoId", "messageId", "value"], + "properties": { + "convoId": { + "type": "string" + }, + "messageId": { + "type": "string" + }, + "value": { + "type": "string", + "minLength": 1, + "maxLength": 64, + "minGraphemes": 1, + "maxGraphemes": 1 + } + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["message"], + "properties": { + "message": { + "type": "ref", + "ref": "chat.bsky.convo.defs#messageView" + } + } + } + }, + "errors": [ + { + "name": "InvalidConvo" + }, + { + "name": "ReactionNotAllowed", + "description": "Indicates that reactions are not allowed on this message, e.g. because it is a system message." + }, + { + "name": "ReactionMessageDeleted", + "description": "Indicates that the message has been deleted and reactions can no longer be added/removed." + }, + { + "name": "ReactionInvalidValue", + "description": "Indicates the value for the reaction is not acceptable. In general, this means it is not an emoji." + } + ] + } + } +} diff --git a/lexicons/chat/bsky/convo/sendMessage.json b/lexicons/chat/bsky/convo/sendMessage.json new file mode 100644 index 0000000000..8364f0069d --- /dev/null +++ b/lexicons/chat/bsky/convo/sendMessage.json @@ -0,0 +1,44 @@ +{ + "lexicon": 1, + "id": "chat.bsky.convo.sendMessage", + "defs": { + "main": { + "type": "procedure", + "description": "Sends a message to a conversation.", + "errors": [ + { + "name": "ConvoLocked" + }, + { + "name": "InvalidConvo" + }, + { + "name": "ReplyTargetNotFound" + } + ], + "input": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["convoId", "message"], + "properties": { + "convoId": { + "type": "string" + }, + "message": { + "type": "ref", + "ref": "chat.bsky.convo.defs#messageInput" + } + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "ref", + "ref": "chat.bsky.convo.defs#messageView" + } + } + } + } +} diff --git a/lexicons/chat/bsky/convo/sendMessageBatch.json b/lexicons/chat/bsky/convo/sendMessageBatch.json new file mode 100644 index 0000000000..a0a3cf9c01 --- /dev/null +++ b/lexicons/chat/bsky/convo/sendMessageBatch.json @@ -0,0 +1,67 @@ +{ + "lexicon": 1, + "id": "chat.bsky.convo.sendMessageBatch", + "defs": { + "main": { + "type": "procedure", + "description": "Sends a batch of messages to a conversation.", + "errors": [ + { + "name": "ConvoLocked" + }, + { + "name": "InvalidConvo" + }, + { + "name": "ReplyTargetNotFound" + } + ], + "input": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["items"], + "properties": { + "items": { + "type": "array", + "maxLength": 100, + "items": { + "type": "ref", + "ref": "#batchItem" + } + } + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["items"], + "properties": { + "items": { + "type": "array", + "items": { + "type": "ref", + "ref": "chat.bsky.convo.defs#messageView" + } + } + } + } + } + }, + "batchItem": { + "type": "object", + "required": ["convoId", "message"], + "properties": { + "convoId": { + "type": "string" + }, + "message": { + "type": "ref", + "ref": "chat.bsky.convo.defs#messageInput" + } + } + } + } +} diff --git a/lexicons/chat/bsky/convo/unlockConvo.json b/lexicons/chat/bsky/convo/unlockConvo.json new file mode 100644 index 0000000000..28f921cd0d --- /dev/null +++ b/lexicons/chat/bsky/convo/unlockConvo.json @@ -0,0 +1,46 @@ +{ + "lexicon": 1, + "id": "chat.bsky.convo.unlockConvo", + "defs": { + "main": { + "type": "procedure", + "description": "Unlocks a group convo so it is able to receive new content.", + "errors": [ + { + "name": "InvalidConvo" + }, + { + "name": "InsufficientRole" + }, + { + "name": "ConvoLockedByModeration" + } + ], + "input": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["convoId"], + "properties": { + "convoId": { + "type": "string" + } + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["convo"], + "properties": { + "convo": { + "type": "ref", + "ref": "chat.bsky.convo.defs#convoView" + } + } + } + } + } + } +} diff --git a/lexicons/chat/bsky/convo/unmuteConvo.json b/lexicons/chat/bsky/convo/unmuteConvo.json new file mode 100644 index 0000000000..cdb982a01e --- /dev/null +++ b/lexicons/chat/bsky/convo/unmuteConvo.json @@ -0,0 +1,40 @@ +{ + "lexicon": 1, + "id": "chat.bsky.convo.unmuteConvo", + "defs": { + "main": { + "type": "procedure", + "description": "Unmutes a conversation, allowing notifications related to it.", + "errors": [ + { + "name": "InvalidConvo" + } + ], + "input": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["convoId"], + "properties": { + "convoId": { + "type": "string" + } + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["convo"], + "properties": { + "convo": { + "type": "ref", + "ref": "chat.bsky.convo.defs#convoView" + } + } + } + } + } + } +} diff --git a/lexicons/chat/bsky/convo/updateAllRead.json b/lexicons/chat/bsky/convo/updateAllRead.json new file mode 100644 index 0000000000..75bb7156c4 --- /dev/null +++ b/lexicons/chat/bsky/convo/updateAllRead.json @@ -0,0 +1,35 @@ +{ + "lexicon": 1, + "id": "chat.bsky.convo.updateAllRead", + "defs": { + "main": { + "type": "procedure", + "description": "Sets conversations from a user as read to the latest message, with filters.", + "input": { + "encoding": "application/json", + "schema": { + "type": "object", + "properties": { + "status": { + "type": "string", + "knownValues": ["request", "accepted"] + } + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["updatedCount"], + "properties": { + "updatedCount": { + "description": "The count of updated convos.", + "type": "integer" + } + } + } + } + } + } +} diff --git a/lexicons/chat/bsky/convo/updateRead.json b/lexicons/chat/bsky/convo/updateRead.json new file mode 100644 index 0000000000..f2c788095f --- /dev/null +++ b/lexicons/chat/bsky/convo/updateRead.json @@ -0,0 +1,43 @@ +{ + "lexicon": 1, + "id": "chat.bsky.convo.updateRead", + "defs": { + "main": { + "type": "procedure", + "description": "Updates the read state of a conversation from, optionally specifying the last read message.", + "errors": [ + { + "name": "InvalidConvo" + } + ], + "input": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["convoId"], + "properties": { + "convoId": { + "type": "string" + }, + "messageId": { + "type": "string" + } + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["convo"], + "properties": { + "convo": { + "type": "ref", + "ref": "chat.bsky.convo.defs#convoView" + } + } + } + } + } + } +} diff --git a/lexicons/chat/bsky/embed/joinLink.json b/lexicons/chat/bsky/embed/joinLink.json new file mode 100644 index 0000000000..345e340425 --- /dev/null +++ b/lexicons/chat/bsky/embed/joinLink.json @@ -0,0 +1,31 @@ +{ + "lexicon": 1, + "id": "chat.bsky.embed.joinLink", + "description": "A join link embedded in a chat message.", + "defs": { + "main": { + "type": "object", + "required": ["code"], + "properties": { + "code": { + "type": "string", + "description": "The join link code." + } + } + }, + "view": { + "type": "object", + "required": ["joinLinkPreview"], + "properties": { + "joinLinkPreview": { + "type": "union", + "refs": [ + "chat.bsky.group.defs#joinLinkPreviewView", + "chat.bsky.group.defs#disabledJoinLinkPreviewView", + "chat.bsky.group.defs#invalidJoinLinkPreviewView" + ] + } + } + } + } +} diff --git a/lexicons/chat/bsky/group/addMembers.json b/lexicons/chat/bsky/group/addMembers.json new file mode 100644 index 0000000000..38af41808c --- /dev/null +++ b/lexicons/chat/bsky/group/addMembers.json @@ -0,0 +1,82 @@ +{ + "lexicon": 1, + "id": "chat.bsky.group.addMembers", + "defs": { + "main": { + "type": "procedure", + "description": "Adds members to a group. The members are added in 'request' status, so they have to accept it. This creates convo memberships.", + "errors": [ + { + "name": "AccountSuspended" + }, + { + "name": "BlockedActor" + }, + { + "name": "BlockedSubject" + }, + { + "name": "ConvoLocked" + }, + { + "name": "InsufficientRole" + }, + { + "name": "InvalidConvo" + }, + { + "name": "MemberLimitReached" + }, + { + "name": "NotFollowedBySender" + }, + { + "name": "RecipientNotFound" + }, + { + "name": "UserForbidsGroups" + } + ], + "input": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["convoId", "members"], + "properties": { + "convoId": { + "type": "string" + }, + "members": { + "type": "array", + "items": { + "type": "string", + "format": "did" + }, + "minLength": 1 + } + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["convo"], + "properties": { + "convo": { + "type": "ref", + "ref": "chat.bsky.convo.defs#convoView" + }, + "addedMembers": { + "type": "array", + "items": { + "type": "ref", + "ref": "chat.bsky.actor.defs#profileViewBasic" + } + } + } + } + } + } + } +} diff --git a/lexicons/chat/bsky/group/approveJoinRequest.json b/lexicons/chat/bsky/group/approveJoinRequest.json new file mode 100644 index 0000000000..78dd55de19 --- /dev/null +++ b/lexicons/chat/bsky/group/approveJoinRequest.json @@ -0,0 +1,50 @@ +{ + "lexicon": 1, + "id": "chat.bsky.group.approveJoinRequest", + "defs": { + "main": { + "type": "procedure", + "description": "Approves a request to join a group (via join link) the user owns. Action taken by the group owner.", + "errors": [ + { + "name": "InvalidConvo" + }, + { + "name": "InsufficientRole" + }, + { + "name": "MemberLimitReached" + } + ], + "input": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["convoId", "member"], + "properties": { + "convoId": { + "type": "string" + }, + "member": { + "type": "string", + "format": "did" + } + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["convo"], + "properties": { + "convo": { + "type": "ref", + "ref": "chat.bsky.convo.defs#convoView" + } + } + } + } + } + } +} diff --git a/lexicons/chat/bsky/group/createGroup.json b/lexicons/chat/bsky/group/createGroup.json new file mode 100644 index 0000000000..8e3442c25c --- /dev/null +++ b/lexicons/chat/bsky/group/createGroup.json @@ -0,0 +1,69 @@ +{ + "lexicon": 1, + "id": "chat.bsky.group.createGroup", + "defs": { + "main": { + "type": "procedure", + "description": "Creates a group convo, specifying the members to be added to it. Unlike getConvoForMembers, this isn't idempotent. It will create new groups even if the membership is identical to pre-existing groups. Will create 'request' membership for all members, except the owner who is 'accepted'.", + "errors": [ + { + "name": "AccountSuspended" + }, + { + "name": "BlockedActor" + }, + { + "name": "BlockedSubject" + }, + { + "name": "NewAccountCannotCreateGroup" + }, + { + "name": "NotFollowedBySender" + }, + { + "name": "RecipientNotFound" + }, + { + "name": "UserForbidsGroups" + } + ], + "input": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["members", "name"], + "properties": { + "members": { + "type": "array", + "maxLength": 49, + "items": { + "type": "string", + "format": "did" + } + }, + "name": { + "type": "string", + "minLength": 1, + "maxGraphemes": 50, + "maxLength": 500 + } + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["convo"], + "properties": { + "convo": { + "type": "ref", + "ref": "chat.bsky.convo.defs#convoView" + } + } + } + } + } + } +} diff --git a/lexicons/chat/bsky/group/createJoinLink.json b/lexicons/chat/bsky/group/createJoinLink.json new file mode 100644 index 0000000000..53bd045238 --- /dev/null +++ b/lexicons/chat/bsky/group/createJoinLink.json @@ -0,0 +1,54 @@ +{ + "lexicon": 1, + "id": "chat.bsky.group.createJoinLink", + "defs": { + "main": { + "type": "procedure", + "description": "Creates a join link for the group convo.", + "errors": [ + { + "name": "EnabledJoinLinkAlreadyExists" + }, + { + "name": "InvalidConvo" + }, + { + "name": "InsufficientRole" + } + ], + "input": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["convoId", "joinRule"], + "properties": { + "convoId": { + "type": "string" + }, + "requireApproval": { + "type": "boolean", + "default": false + }, + "joinRule": { + "type": "ref", + "ref": "chat.bsky.group.defs#joinRule" + } + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["joinLink"], + "properties": { + "joinLink": { + "type": "ref", + "ref": "chat.bsky.group.defs#joinLinkView" + } + } + } + } + } + } +} diff --git a/lexicons/chat/bsky/group/defs.json b/lexicons/chat/bsky/group/defs.json new file mode 100644 index 0000000000..174a773669 --- /dev/null +++ b/lexicons/chat/bsky/group/defs.json @@ -0,0 +1,177 @@ +{ + "lexicon": 1, + "id": "chat.bsky.group.defs", + "defs": { + "linkEnabledStatus": { + "type": "string", + "knownValues": ["enabled", "disabled"] + }, + "joinRule": { + "type": "string", + "knownValues": ["anyone", "followedByOwner"] + }, + "joinLinkView": { + "description": "Join link view to be used within a group view, so the convo is surrounding, not specified inside this view.", + "type": "object", + "required": [ + "code", + "enabledStatus", + "requireApproval", + "joinRule", + "createdAt" + ], + "properties": { + "code": { + "type": "string" + }, + "enabledStatus": { + "type": "ref", + "ref": "#linkEnabledStatus" + }, + "requireApproval": { + "type": "boolean" + }, + "joinRule": { + "type": "ref", + "ref": "#joinRule" + }, + "createdAt": { + "type": "string", + "format": "datetime" + } + } + }, + "joinLinkPreviewView": { + "description": "Preview that can be shown in feeds, including to unauthenticated viewers.", + "type": "object", + "required": [ + "convoId", + "code", + "name", + "owner", + "memberCount", + "memberLimit", + "requireApproval", + "joinRule" + ], + "properties": { + "convoId": { + "type": "string" + }, + "code": { + "type": "string" + }, + "name": { + "type": "string" + }, + "owner": { + "type": "ref", + "ref": "chat.bsky.actor.defs#profileViewBasic" + }, + "memberCount": { + "type": "integer" + }, + "memberLimit": { + "type": "integer" + }, + "requireApproval": { + "type": "boolean" + }, + "joinRule": { + "type": "ref", + "ref": "#joinRule" + }, + "convo": { + "type": "ref", + "ref": "chat.bsky.convo.defs#convoView", + "description": "Present only if the request is authenticated and the user is a member of the group." + }, + "viewer": { + "type": "ref", + "ref": "#joinLinkViewerState" + } + } + }, + "disabledJoinLinkPreviewView": { + "description": "Preview for a disabled join link. Carries only the code so clients can correlate with the input and render a disabled state.", + "type": "object", + "required": ["code"], + "properties": { + "code": { + "type": "string" + } + } + }, + "invalidJoinLinkPreviewView": { + "description": "Preview for a join link code that does not map to an existing link. Carries only the code so clients can correlate with the input and render an invalid state.", + "type": "object", + "required": ["code"], + "properties": { + "code": { + "type": "string" + } + } + }, + "joinLinkViewerState": { + "type": "object", + "properties": { + "requestedAt": { + "type": "string", + "format": "datetime" + } + } + }, + "joinRequestView": { + "description": "A join request from the perspective of the group owner.", + "type": "object", + "required": ["convoId", "requestedBy", "requestedAt"], + "properties": { + "convoId": { + "type": "string" + }, + "requestedBy": { + "type": "ref", + "ref": "chat.bsky.actor.defs#profileViewBasic" + }, + "requestedAt": { + "type": "string", + "format": "datetime" + } + } + }, + "joinRequestConvoView": { + "description": "A join request from the perspective of the requester, including enough group context to render the request in a list (e.g. group name, owner, member count).", + "type": "object", + "required": [ + "convoId", + "name", + "owner", + "memberCount", + "memberLimit", + "viewer" + ], + "properties": { + "convoId": { + "type": "string" + }, + "name": { + "type": "string" + }, + "owner": { + "type": "ref", + "ref": "chat.bsky.actor.defs#profileViewBasic" + }, + "memberCount": { + "type": "integer" + }, + "memberLimit": { + "type": "integer" + }, + "viewer": { + "type": "ref", + "ref": "#joinLinkViewerState" + } + } + } + } +} diff --git a/lexicons/chat/bsky/group/disableJoinLink.json b/lexicons/chat/bsky/group/disableJoinLink.json new file mode 100644 index 0000000000..b2f07b465b --- /dev/null +++ b/lexicons/chat/bsky/group/disableJoinLink.json @@ -0,0 +1,46 @@ +{ + "lexicon": 1, + "id": "chat.bsky.group.disableJoinLink", + "defs": { + "main": { + "type": "procedure", + "description": "Disables the active join link for the group convo.", + "errors": [ + { + "name": "InvalidConvo" + }, + { + "name": "InsufficientRole" + }, + { + "name": "NoJoinLink" + } + ], + "input": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["convoId"], + "properties": { + "convoId": { + "type": "string" + } + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["joinLink"], + "properties": { + "joinLink": { + "type": "ref", + "ref": "chat.bsky.group.defs#joinLinkView" + } + } + } + } + } + } +} diff --git a/lexicons/chat/bsky/group/editGroup.json b/lexicons/chat/bsky/group/editGroup.json new file mode 100644 index 0000000000..59de90ce8f --- /dev/null +++ b/lexicons/chat/bsky/group/editGroup.json @@ -0,0 +1,52 @@ +{ + "lexicon": 1, + "id": "chat.bsky.group.editGroup", + "defs": { + "main": { + "type": "procedure", + "description": "Edits group settings.", + "errors": [ + { + "name": "ConvoLocked" + }, + { + "name": "InvalidConvo" + }, + { + "name": "InsufficientRole" + } + ], + "input": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["convoId", "name"], + "properties": { + "convoId": { + "type": "string" + }, + "name": { + "type": "string", + "minLength": 1, + "maxGraphemes": 50, + "maxLength": 500 + } + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["convo"], + "properties": { + "convo": { + "type": "ref", + "ref": "chat.bsky.convo.defs#convoView" + } + } + } + } + } + } +} diff --git a/lexicons/chat/bsky/group/editJoinLink.json b/lexicons/chat/bsky/group/editJoinLink.json new file mode 100644 index 0000000000..5dae494937 --- /dev/null +++ b/lexicons/chat/bsky/group/editJoinLink.json @@ -0,0 +1,53 @@ +{ + "lexicon": 1, + "id": "chat.bsky.group.editJoinLink", + "defs": { + "main": { + "type": "procedure", + "description": "Edits the existing join link settings for the group convo.", + "errors": [ + { + "name": "InvalidConvo" + }, + { + "name": "InsufficientRole" + }, + { + "name": "NoJoinLink" + } + ], + "input": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["convoId"], + "properties": { + "convoId": { + "type": "string" + }, + "requireApproval": { + "type": "boolean" + }, + "joinRule": { + "type": "ref", + "ref": "chat.bsky.group.defs#joinRule" + } + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["joinLink"], + "properties": { + "joinLink": { + "type": "ref", + "ref": "chat.bsky.group.defs#joinLinkView" + } + } + } + } + } + } +} diff --git a/lexicons/chat/bsky/group/enableJoinLink.json b/lexicons/chat/bsky/group/enableJoinLink.json new file mode 100644 index 0000000000..ce846c08d4 --- /dev/null +++ b/lexicons/chat/bsky/group/enableJoinLink.json @@ -0,0 +1,49 @@ +{ + "lexicon": 1, + "id": "chat.bsky.group.enableJoinLink", + "defs": { + "main": { + "type": "procedure", + "description": "Re-enables a previously disabled join link for the group convo.", + "errors": [ + { + "name": "InvalidConvo" + }, + { + "name": "InsufficientRole" + }, + { + "name": "NoJoinLink" + }, + { + "name": "LinkAlreadyEnabled" + } + ], + "input": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["convoId"], + "properties": { + "convoId": { + "type": "string" + } + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["joinLink"], + "properties": { + "joinLink": { + "type": "ref", + "ref": "chat.bsky.group.defs#joinLinkView" + } + } + } + } + } + } +} diff --git a/lexicons/chat/bsky/group/getJoinLinkPreviews.json b/lexicons/chat/bsky/group/getJoinLinkPreviews.json new file mode 100644 index 0000000000..520cf1f9d1 --- /dev/null +++ b/lexicons/chat/bsky/group/getJoinLinkPreviews.json @@ -0,0 +1,44 @@ +{ + "lexicon": 1, + "id": "chat.bsky.group.getJoinLinkPreviews", + "defs": { + "main": { + "type": "query", + "description": "Get public information about groups from join links. The output array matches the input codes one-to-one by position (and each view also carries its 'code'). Disabled codes return a disabledJoinLinkPreviewView, and codes that do not map to a previewable link return an invalidJoinLinkPreviewView.", + "parameters": { + "type": "params", + "required": ["codes"], + "properties": { + "codes": { + "type": "array", + "minLength": 1, + "maxLength": 50, + "items": { + "type": "string" + } + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["joinLinkPreviews"], + "properties": { + "joinLinkPreviews": { + "type": "array", + "items": { + "type": "union", + "refs": [ + "chat.bsky.group.defs#joinLinkPreviewView", + "chat.bsky.group.defs#disabledJoinLinkPreviewView", + "chat.bsky.group.defs#invalidJoinLinkPreviewView" + ] + } + } + } + } + } + } + } +} diff --git a/lexicons/chat/bsky/group/listJoinRequests.json b/lexicons/chat/bsky/group/listJoinRequests.json new file mode 100644 index 0000000000..a252bccf9f --- /dev/null +++ b/lexicons/chat/bsky/group/listJoinRequests.json @@ -0,0 +1,55 @@ +{ + "lexicon": 1, + "id": "chat.bsky.group.listJoinRequests", + "defs": { + "main": { + "type": "query", + "description": "Lists a page of request to join a group (via join link) the user owns. Shows the data from the owner's point of view.", + "errors": [ + { + "name": "InvalidConvo" + }, + { + "name": "InsufficientRole" + } + ], + "parameters": { + "type": "params", + "required": ["convoId"], + "properties": { + "convoId": { + "type": "string" + }, + "limit": { + "type": "integer", + "minimum": 1, + "maximum": 100, + "default": 50 + }, + "cursor": { + "type": "string" + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["requests"], + "properties": { + "cursor": { + "type": "string" + }, + "requests": { + "type": "array", + "items": { + "type": "ref", + "ref": "chat.bsky.group.defs#joinRequestView" + } + } + } + } + } + } + } +} diff --git a/lexicons/chat/bsky/group/listMutualGroups.json b/lexicons/chat/bsky/group/listMutualGroups.json new file mode 100644 index 0000000000..1ed78dd660 --- /dev/null +++ b/lexicons/chat/bsky/group/listMutualGroups.json @@ -0,0 +1,48 @@ +{ + "lexicon": 1, + "id": "chat.bsky.group.listMutualGroups", + "defs": { + "main": { + "type": "query", + "description": "Returns a page of group conversations that both the requester and the specified actor are members of.", + "parameters": { + "type": "params", + "required": ["subject"], + "properties": { + "subject": { + "type": "string", + "format": "did" + }, + "limit": { + "type": "integer", + "minimum": 1, + "maximum": 100, + "default": 50 + }, + "cursor": { + "type": "string" + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["convos"], + "properties": { + "cursor": { + "type": "string" + }, + "convos": { + "type": "array", + "items": { + "type": "ref", + "ref": "chat.bsky.convo.defs#convoView" + } + } + } + } + } + } + } +} diff --git a/lexicons/chat/bsky/group/rejectJoinRequest.json b/lexicons/chat/bsky/group/rejectJoinRequest.json new file mode 100644 index 0000000000..ad9b3ff2f1 --- /dev/null +++ b/lexicons/chat/bsky/group/rejectJoinRequest.json @@ -0,0 +1,42 @@ +{ + "lexicon": 1, + "id": "chat.bsky.group.rejectJoinRequest", + "defs": { + "main": { + "type": "procedure", + "description": "Rejects a request to join a group (via join link) the user owns. Action taken by the group owner.", + "errors": [ + { + "name": "InvalidConvo" + }, + { + "name": "InsufficientRole" + } + ], + "input": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["convoId", "member"], + "properties": { + "convoId": { + "type": "string" + }, + "member": { + "type": "string", + "format": "did" + } + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": [], + "properties": {} + } + } + } + } +} diff --git a/lexicons/chat/bsky/group/removeMembers.json b/lexicons/chat/bsky/group/removeMembers.json new file mode 100644 index 0000000000..bba0ec6294 --- /dev/null +++ b/lexicons/chat/bsky/group/removeMembers.json @@ -0,0 +1,51 @@ +{ + "lexicon": 1, + "id": "chat.bsky.group.removeMembers", + "defs": { + "main": { + "type": "procedure", + "description": "Removes members from a group. This deletes convo memberships, doesn't just set a status.", + "errors": [ + { + "name": "InvalidConvo" + }, + { + "name": "InsufficientRole" + } + ], + "input": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["convoId", "members"], + "properties": { + "convoId": { + "type": "string" + }, + "members": { + "type": "array", + "items": { + "type": "string", + "format": "did" + }, + "minLength": 1 + } + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["convo"], + "properties": { + "convo": { + "type": "ref", + "ref": "chat.bsky.convo.defs#convoView" + } + } + } + } + } + } +} diff --git a/lexicons/chat/bsky/group/requestJoin.json b/lexicons/chat/bsky/group/requestJoin.json new file mode 100644 index 0000000000..953564514c --- /dev/null +++ b/lexicons/chat/bsky/group/requestJoin.json @@ -0,0 +1,60 @@ +{ + "lexicon": 1, + "id": "chat.bsky.group.requestJoin", + "defs": { + "main": { + "type": "procedure", + "description": "Sends a request to join a group (via join link) to the group owner. Action taken by the prospective group member.", + "errors": [ + { + "name": "ConvoLocked" + }, + { + "name": "FollowRequired" + }, + { + "name": "InvalidCode" + }, + { + "name": "LinkDisabled" + }, + { + "name": "MemberLimitReached" + }, + { + "name": "UserKicked" + } + ], + "input": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["code"], + "properties": { + "code": { + "type": "string" + } + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["status"], + "properties": { + "status": { + "type": "string", + "knownValues": ["joined", "pending"] + }, + "convo": { + "description": "The group convo joined. This is only present in the case of status=joined", + "type": "ref", + "ref": "chat.bsky.convo.defs#convoView" + } + } + } + } + } + } +} diff --git a/lexicons/chat/bsky/group/updateJoinRequestsRead.json b/lexicons/chat/bsky/group/updateJoinRequestsRead.json new file mode 100644 index 0000000000..897bea3c6e --- /dev/null +++ b/lexicons/chat/bsky/group/updateJoinRequestsRead.json @@ -0,0 +1,38 @@ +{ + "lexicon": 1, + "id": "chat.bsky.group.updateJoinRequestsRead", + "defs": { + "main": { + "type": "procedure", + "description": "Marks all join requests as read for the group owner.", + "errors": [ + { + "name": "InvalidConvo" + }, + { + "name": "InsufficientRole" + } + ], + "input": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["convoId"], + "properties": { + "convoId": { + "type": "string" + } + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": [], + "properties": {} + } + } + } + } +} diff --git a/lexicons/chat/bsky/group/withdrawJoinRequest.json b/lexicons/chat/bsky/group/withdrawJoinRequest.json new file mode 100644 index 0000000000..2c773ea5d0 --- /dev/null +++ b/lexicons/chat/bsky/group/withdrawJoinRequest.json @@ -0,0 +1,35 @@ +{ + "lexicon": 1, + "id": "chat.bsky.group.withdrawJoinRequest", + "defs": { + "main": { + "type": "procedure", + "description": "Withdraws a pending request to join a group. Action taken by the prospective member who originally requested to join.", + "errors": [ + { + "name": "InvalidJoinRequest" + } + ], + "input": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["convoId"], + "properties": { + "convoId": { + "type": "string" + } + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": [], + "properties": {} + } + } + } + } +} diff --git a/lexicons/chat/bsky/moderation/defs.json b/lexicons/chat/bsky/moderation/defs.json new file mode 100644 index 0000000000..860f28bf14 --- /dev/null +++ b/lexicons/chat/bsky/moderation/defs.json @@ -0,0 +1,74 @@ +{ + "lexicon": 1, + "id": "chat.bsky.moderation.defs", + "defs": { + "convoView": { + "description": "A view of a conversation for moderation purposes. Unlike chat.bsky.convo.defs#convoView, it does not include viewer-specific data (such as muted, unreadCount, status, lastMessage, lastReaction), since the requester is a moderator and not a member of the conversation. The member list is not included; use chat.bsky.moderation.getConvoMembers to list members.", + "type": "object", + "required": ["id", "rev"], + "properties": { + "id": { + "type": "string" + }, + "rev": { + "type": "string" + }, + "kind": { + "description": "Union field that has data specific to different kinds of convos.", + "type": "union", + "refs": ["#directConvo", "#groupConvo"] + } + } + }, + "directConvo": { + "description": "Data specific to a direct conversation, for moderation purposes.", + "type": "object", + "properties": {} + }, + "groupConvo": { + "description": "Data specific to a group conversation, for moderation purposes. Unlike chat.bsky.convo.defs#groupConvo, it does not include viewer-specific data (such as unreadJoinRequestCount), since the requester is a moderator and not a member of the conversation.", + "type": "object", + "required": [ + "createdAt", + "joinRequestCount", + "lockStatus", + "memberCount", + "memberLimit", + "name" + ], + "properties": { + "createdAt": { + "type": "string", + "format": "datetime" + }, + "joinLink": { + "type": "ref", + "ref": "chat.bsky.group.defs#joinLinkView" + }, + "joinRequestCount": { + "type": "integer", + "description": "The total number of pending join requests for the group conversation. This information is only visible to the owner and to moderators. Capped at 21." + }, + "lockStatus": { + "description": "The lock status of the conversation.", + "type": "ref", + "ref": "chat.bsky.convo.defs#convoLockStatus" + }, + "memberCount": { + "type": "integer", + "description": "The total number of members in the group conversation." + }, + "memberLimit": { + "type": "integer", + "description": "The maximum number of members allowed in the group conversation." + }, + "name": { + "type": "string", + "description": "The display name of the group conversation.", + "maxGraphemes": 50, + "maxLength": 500 + } + } + } + } +} diff --git a/lexicons/chat/bsky/moderation/getActorMetadata.json b/lexicons/chat/bsky/moderation/getActorMetadata.json new file mode 100644 index 0000000000..e384553ba2 --- /dev/null +++ b/lexicons/chat/bsky/moderation/getActorMetadata.json @@ -0,0 +1,63 @@ +{ + "lexicon": 1, + "id": "chat.bsky.moderation.getActorMetadata", + "defs": { + "main": { + "type": "query", + "parameters": { + "type": "params", + "required": ["actor"], + "properties": { + "actor": { + "type": "string", + "format": "did" + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["day", "month", "all"], + "properties": { + "day": { + "type": "ref", + "ref": "#metadata" + }, + "month": { + "type": "ref", + "ref": "#metadata" + }, + "all": { + "type": "ref", + "ref": "#metadata" + } + } + } + } + }, + "metadata": { + "type": "object", + "required": [ + "messagesSent", + "messagesReceived", + "convos", + "convosStarted" + ], + "properties": { + "messagesSent": { + "type": "integer" + }, + "messagesReceived": { + "type": "integer" + }, + "convos": { + "type": "integer" + }, + "convosStarted": { + "type": "integer" + } + } + } + } +} diff --git a/lexicons/chat/bsky/moderation/getConvo.json b/lexicons/chat/bsky/moderation/getConvo.json new file mode 100644 index 0000000000..15c42aaaf0 --- /dev/null +++ b/lexicons/chat/bsky/moderation/getConvo.json @@ -0,0 +1,37 @@ +{ + "lexicon": 1, + "id": "chat.bsky.moderation.getConvo", + "defs": { + "main": { + "type": "query", + "description": "Gets an existing conversation by its ID, for moderation purposes. Does not require the requester to be a member of the conversation.", + "errors": [ + { + "name": "InvalidConvo" + } + ], + "parameters": { + "type": "params", + "required": ["convoId"], + "properties": { + "convoId": { + "type": "string" + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["convo"], + "properties": { + "convo": { + "type": "ref", + "ref": "chat.bsky.moderation.defs#convoView" + } + } + } + } + } + } +} diff --git a/lexicons/chat/bsky/moderation/getConvoMembers.json b/lexicons/chat/bsky/moderation/getConvoMembers.json new file mode 100644 index 0000000000..064b209126 --- /dev/null +++ b/lexicons/chat/bsky/moderation/getConvoMembers.json @@ -0,0 +1,52 @@ +{ + "lexicon": 1, + "id": "chat.bsky.moderation.getConvoMembers", + "defs": { + "main": { + "type": "query", + "description": "Returns a paginated list of members from a conversation, for moderation purposes. Does not require the requester to be a member of the conversation.", + "errors": [ + { + "name": "InvalidConvo" + } + ], + "parameters": { + "type": "params", + "required": ["convoId"], + "properties": { + "convoId": { + "type": "string" + }, + "limit": { + "type": "integer", + "minimum": 1, + "maximum": 100, + "default": 50 + }, + "cursor": { + "type": "string" + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["members"], + "properties": { + "cursor": { + "type": "string" + }, + "members": { + "type": "array", + "items": { + "type": "ref", + "ref": "chat.bsky.actor.defs#profileViewBasic" + } + } + } + } + } + } + } +} diff --git a/lexicons/chat/bsky/moderation/getConvos.json b/lexicons/chat/bsky/moderation/getConvos.json new file mode 100644 index 0000000000..0ef99b5797 --- /dev/null +++ b/lexicons/chat/bsky/moderation/getConvos.json @@ -0,0 +1,40 @@ +{ + "lexicon": 1, + "id": "chat.bsky.moderation.getConvos", + "defs": { + "main": { + "type": "query", + "description": "Gets existing conversations by their IDs, for moderation purposes. Does not require the requester to be a member of the conversations. Unknown IDs are silently omitted from the response.", + "parameters": { + "type": "params", + "required": ["convoIds"], + "properties": { + "convoIds": { + "type": "array", + "minLength": 1, + "maxLength": 100, + "items": { + "type": "string" + } + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["convos"], + "properties": { + "convos": { + "type": "array", + "items": { + "type": "ref", + "ref": "chat.bsky.moderation.defs#convoView" + } + } + } + } + } + } + } +} diff --git a/lexicons/chat/bsky/moderation/getMessageContext.json b/lexicons/chat/bsky/moderation/getMessageContext.json new file mode 100644 index 0000000000..1ddb9e5dc0 --- /dev/null +++ b/lexicons/chat/bsky/moderation/getMessageContext.json @@ -0,0 +1,58 @@ +{ + "lexicon": 1, + "id": "chat.bsky.moderation.getMessageContext", + "defs": { + "main": { + "type": "query", + "parameters": { + "type": "params", + "required": ["messageId"], + "properties": { + "convoId": { + "type": "string", + "description": "Conversation that the message is from. NOTE: this field will eventually be required." + }, + "messageId": { + "type": "string" + }, + "before": { + "type": "integer", + "default": 5, + "description": "Number of user messages before the target to include. System messages between the earliest returned user message and the target are also included, capped per gap by `maxInterleavedSystemMessages`. If there are no user messages before the target, up to `maxInterleavedSystemMessages` system messages immediately preceding the target are returned instead." + }, + "after": { + "type": "integer", + "default": 5, + "description": "Number of user messages after the target to include. System messages between the target and the latest returned user message are also included, capped per gap by `maxInterleavedSystemMessages`. If there are no user messages after the target, up to `maxInterleavedSystemMessages` system messages immediately following the target are returned instead." + }, + "maxInterleavedSystemMessages": { + "type": "integer", + "default": 10, + "minimum": 0, + "maximum": 1000, + "description": "Maximum number of system messages to include per gap between consecutive returned messages (and per side when there are no user messages on that side). Within a gap, the system messages closest to the earlier message are kept." + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["messages"], + "properties": { + "messages": { + "type": "array", + "items": { + "type": "union", + "refs": [ + "chat.bsky.convo.defs#messageView", + "chat.bsky.convo.defs#systemMessageView" + ] + } + } + } + } + } + } + } +} diff --git a/lexicons/chat/bsky/moderation/subscribeModEvents.json b/lexicons/chat/bsky/moderation/subscribeModEvents.json new file mode 100644 index 0000000000..4fa5893d11 --- /dev/null +++ b/lexicons/chat/bsky/moderation/subscribeModEvents.json @@ -0,0 +1,657 @@ +{ + "lexicon": 1, + "id": "chat.bsky.moderation.subscribeModEvents", + "defs": { + "main": { + "type": "subscription", + "description": "Subscribe to stream of chat events targeted to moderation. Private endpoint.", + "parameters": { + "type": "params", + "properties": { + "cursor": { + "type": "string", + "description": "The last known event seq number to backfill from. Use '2222222222222' to backfill from the beginning. Don't specify a cursor to listen only for new events." + } + } + }, + "message": { + "schema": { + "type": "union", + "refs": [ + "#eventConvoFirstMessage", + "#eventGroupChatCreated", + "#eventGroupChatMemberAdded", + "#eventGroupChatMemberJoined", + "#eventGroupChatJoinRequest", + "#eventGroupChatJoinRequestApproved", + "#eventGroupChatJoinRequestRejected", + "#eventChatAccepted", + "#eventGroupChatMemberLeft", + "#eventGroupChatUpdated", + "#eventRateLimitExceeded" + ] + } + }, + "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." + } + ] + }, + "eventConvoFirstMessage": { + "type": "object", + "description": "Fired when the first message was sent on a convo.", + "required": ["createdAt", "rev", "convoId", "user", "recipients"], + "properties": { + "convoId": { + "type": "string" + }, + "createdAt": { + "type": "string", + "format": "datetime" + }, + "messageId": { + "type": "string" + }, + "recipients": { + "description": "The list of DIDs message recipients. Does not include the sender, which is in the `user` field", + "type": "array", + "items": { + "type": "string", + "format": "did" + } + }, + "rev": { + "type": "string" + }, + "user": { + "description": "The DID of the message author.", + "type": "string", + "format": "did" + } + } + }, + "eventGroupChatCreated": { + "type": "object", + "description": "Fire when a group chat is created.", + "required": [ + "actorDid", + "convoCreatedAt", + "convoId", + "createdAt", + "groupMemberCount", + "groupName", + "initialMemberDids", + "ownerDid", + "rev" + ], + "properties": { + "actorDid": { + "description": "The DID of the actor performing the action. For this event, same as ownerDid.", + "type": "string", + "format": "did" + }, + "convoCreatedAt": { + "description": "When the group was originally created.", + "type": "string", + "format": "datetime" + }, + "convoId": { + "type": "string" + }, + "createdAt": { + "type": "string", + "format": "datetime" + }, + "groupMemberCount": { + "description": "Current member count at the time of the event.", + "type": "integer" + }, + "groupName": { + "description": "The name set at creation time.", + "type": "string" + }, + "initialMemberDids": { + "description": "DIDs of everyone added at creation time.", + "type": "array", + "items": { + "type": "string", + "format": "did" + } + }, + "ownerDid": { + "description": "The DID of the group chat owner.", + "type": "string", + "format": "did" + }, + "rev": { + "type": "string" + } + } + }, + "eventGroupChatMemberAdded": { + "type": "object", + "description": "Fired when a member is added to a group chat. Note that members are added in the 'request' state.", + "required": [ + "actorDid", + "convoCreatedAt", + "convoId", + "createdAt", + "groupMemberCount", + "groupName", + "ownerDid", + "requestMembersCount", + "rev", + "subjectDid", + "subjectFollowsOwner" + ], + "properties": { + "actorDid": { + "description": "The DID of the actor performing the action. For this event, same as ownerDid.", + "type": "string", + "format": "did" + }, + "convoCreatedAt": { + "description": "When the group was originally created.", + "type": "string", + "format": "datetime" + }, + "convoId": { + "type": "string" + }, + "createdAt": { + "type": "string", + "format": "datetime" + }, + "groupMemberCount": { + "description": "Current member count at the time of the event.", + "type": "integer" + }, + "groupName": { + "type": "string" + }, + "ownerDid": { + "description": "The DID of the group chat owner.", + "type": "string", + "format": "did" + }, + "requestMembersCount": { + "description": "The number of members who have not yet accepted the convo.", + "type": "integer" + }, + "rev": { + "type": "string" + }, + "subjectDid": { + "description": "The DID of the member who was added.", + "type": "string", + "format": "did" + }, + "subjectFollowsOwner": { + "description": "Whether the added member follows the group owner.", + "type": "boolean" + } + } + }, + "eventGroupChatMemberJoined": { + "type": "object", + "description": "Fired when a member joins a group chat via an join link that does not require approval.", + "required": [ + "actorDid", + "convoCreatedAt", + "convoId", + "createdAt", + "groupMemberCount", + "groupName", + "joinLinkCode", + "ownerDid", + "rev", + "subjectFollowsOwner" + ], + "properties": { + "actorDid": { + "description": "The DID of the person joining.", + "type": "string", + "format": "did" + }, + "convoCreatedAt": { + "description": "When the group was originally created.", + "type": "string", + "format": "datetime" + }, + "convoId": { + "type": "string" + }, + "createdAt": { + "type": "string", + "format": "datetime" + }, + "groupMemberCount": { + "description": "Current member count at the time of the event.", + "type": "integer" + }, + "groupName": { + "type": "string" + }, + "joinLinkCode": { + "description": "The code of the join link used to join.", + "type": "string" + }, + "ownerDid": { + "description": "The DID of the group chat owner.", + "type": "string", + "format": "did" + }, + "rev": { + "type": "string" + }, + "subjectFollowsOwner": { + "description": "Whether the joining member follows the group owner.", + "type": "boolean" + } + } + }, + "eventGroupChatJoinRequest": { + "type": "object", + "description": "Fired when a user requests to join a group chat via an join link that requires approval.", + "required": [ + "actorDid", + "convoCreatedAt", + "convoId", + "createdAt", + "groupMemberCount", + "groupName", + "joinLinkCode", + "ownerDid", + "rev", + "subjectFollowsOwner" + ], + "properties": { + "actorDid": { + "description": "The DID of the person requesting to join.", + "type": "string", + "format": "did" + }, + "convoCreatedAt": { + "description": "When the group was originally created.", + "type": "string", + "format": "datetime" + }, + "convoId": { + "type": "string" + }, + "createdAt": { + "type": "string", + "format": "datetime" + }, + "groupMemberCount": { + "description": "Current member count at the time of the event.", + "type": "integer" + }, + "groupName": { + "type": "string" + }, + "joinLinkCode": { + "description": "The code of the join link used to request joining.", + "type": "string" + }, + "ownerDid": { + "description": "The DID of the group chat owner.", + "type": "string", + "format": "did" + }, + "rev": { + "type": "string" + }, + "subjectFollowsOwner": { + "description": "Whether the requesting member follows the group owner.", + "type": "boolean" + } + } + }, + "eventGroupChatJoinRequestApproved": { + "type": "object", + "description": "Fired when a join request is approved by the group owner.", + "required": [ + "actorDid", + "convoCreatedAt", + "convoId", + "createdAt", + "groupMemberCount", + "groupName", + "ownerDid", + "rev", + "subjectDid" + ], + "properties": { + "actorDid": { + "description": "The DID of the owner approving the request.", + "type": "string", + "format": "did" + }, + "convoCreatedAt": { + "description": "When the group was originally created.", + "type": "string", + "format": "datetime" + }, + "convoId": { + "type": "string" + }, + "createdAt": { + "type": "string", + "format": "datetime" + }, + "groupMemberCount": { + "description": "Current member count at the time of the event.", + "type": "integer" + }, + "groupName": { + "type": "string" + }, + "ownerDid": { + "description": "The DID of the group chat owner.", + "type": "string", + "format": "did" + }, + "rev": { + "type": "string" + }, + "subjectDid": { + "description": "The DID of the member whose request was approved.", + "type": "string", + "format": "did" + } + } + }, + "eventGroupChatJoinRequestRejected": { + "type": "object", + "description": "Fired when a join request is rejected by the group owner.", + "required": [ + "actorDid", + "convoCreatedAt", + "convoId", + "createdAt", + "groupMemberCount", + "groupName", + "ownerDid", + "rev", + "subjectDid" + ], + "properties": { + "actorDid": { + "description": "The DID of the owner rejecting the request.", + "type": "string", + "format": "did" + }, + "convoCreatedAt": { + "description": "When the group was originally created.", + "type": "string", + "format": "datetime" + }, + "convoId": { + "type": "string" + }, + "createdAt": { + "type": "string", + "format": "datetime" + }, + "groupMemberCount": { + "description": "Current member count at the time of the event.", + "type": "integer" + }, + "groupName": { + "type": "string" + }, + "ownerDid": { + "description": "The DID of the group chat owner.", + "type": "string", + "format": "did" + }, + "rev": { + "type": "string" + }, + "subjectDid": { + "description": "The DID of the member whose request was rejected.", + "type": "string", + "format": "did" + } + } + }, + "eventChatAccepted": { + "type": "object", + "description": "Fired when a user accepts a chat convo, either explicitly or by sending a message.", + "required": [ + "actorDid", + "convoCreatedAt", + "convoId", + "createdAt", + "method", + "rev" + ], + "properties": { + "actorDid": { + "description": "The DID of the person accepting the convo.", + "type": "string", + "format": "did" + }, + "convoCreatedAt": { + "description": "When the convo was originally created.", + "type": "string", + "format": "datetime" + }, + "convoId": { + "type": "string" + }, + "createdAt": { + "type": "string", + "format": "datetime" + }, + "groupMemberCount": { + "description": "Current member count at the time of the event. Only present for group convos.", + "type": "integer" + }, + "groupName": { + "description": "The name of the group chat. Only present for group convos.", + "type": "string" + }, + "method": { + "description": "How the convo was accepted.", + "type": "string", + "knownValues": ["explicit", "message"] + }, + "ownerDid": { + "description": "The DID of the group chat owner. Only present for group convos.", + "type": "string", + "format": "did" + }, + "rev": { + "type": "string" + } + } + }, + "eventGroupChatMemberLeft": { + "type": "object", + "description": "Fired when a member leaves or is removed from a group chat.", + "required": [ + "actorDid", + "convoCreatedAt", + "convoId", + "createdAt", + "groupMemberCount", + "groupName", + "leaveMethod", + "ownerDid", + "rev", + "subjectDid" + ], + "properties": { + "actorDid": { + "description": "The DID of the actor. For voluntary: the person leaving. For kicked: the owner.", + "type": "string", + "format": "did" + }, + "convoCreatedAt": { + "description": "When the group was originally created.", + "type": "string", + "format": "datetime" + }, + "convoId": { + "type": "string" + }, + "createdAt": { + "type": "string", + "format": "datetime" + }, + "groupMemberCount": { + "description": "Current member count at the time of the event.", + "type": "integer" + }, + "groupName": { + "type": "string" + }, + "leaveMethod": { + "description": "How the member left.", + "type": "string", + "knownValues": ["voluntary", "kicked"] + }, + "ownerDid": { + "description": "The DID of the group chat owner.", + "type": "string", + "format": "did" + }, + "rev": { + "type": "string" + }, + "subjectDid": { + "description": "The DID of the member who left or was removed.", + "type": "string", + "format": "did" + } + } + }, + "eventGroupChatUpdated": { + "type": "object", + "description": "Fired when a group chat's metadata or status changes.", + "required": [ + "actorDid", + "convoCreatedAt", + "convoId", + "createdAt", + "groupMemberCount", + "groupName", + "ownerDid", + "rev", + "updateType" + ], + "properties": { + "actorDid": { + "description": "The DID of the actor performing the action (the owner).", + "type": "string", + "format": "did" + }, + "convoCreatedAt": { + "description": "When the group was originally created.", + "type": "string", + "format": "datetime" + }, + "convoId": { + "type": "string" + }, + "createdAt": { + "type": "string", + "format": "datetime" + }, + "groupMemberCount": { + "description": "Current member count at the time of the event.", + "type": "integer" + }, + "groupName": { + "description": "Current group name.", + "type": "string" + }, + "joinLinkCode": { + "description": "The code of the join link. Only present when updateType is join-link-related.", + "type": "string" + }, + "joinLinkFollowersOnly": { + "description": "Whether the join link is restricted to followers of the owner. Only present when updateType is join-link-related.", + "type": "boolean" + }, + "joinLinkRequiresApproval": { + "description": "Whether the join link requires owner approval to join. Only present when updateType is join-link-related.", + "type": "boolean" + }, + "lockReason": { + "description": "Why the group was locked. Only present when updateType is 'locked'.", + "type": "string", + "knownValues": [ + "owner_action", + "owner_left", + "owner_deactivated", + "owner_deleted", + "owner_suspended", + "owner_taken_down", + "label_applied", + "convo_taken_down" + ] + }, + "newName": { + "description": "The new group name. Only present when updateType is 'name_changed'.", + "type": "string" + }, + "oldName": { + "description": "The previous group name. Only present when updateType is 'name_changed'.", + "type": "string" + }, + "ownerDid": { + "description": "The DID of the group chat owner.", + "type": "string", + "format": "did" + }, + "rev": { + "type": "string" + }, + "updateType": { + "description": "What changed.", + "type": "string", + "knownValues": [ + "name_changed", + "locked", + "locked_permanently", + "unlocked", + "join_link_created", + "join_link_disabled", + "join_link_settings_changed" + ] + } + } + }, + "eventRateLimitExceeded": { + "type": "object", + "description": "Fired when a user exceeds a rate limit.", + "required": ["actorDid", "createdAt", "endpoint", "rev"], + "properties": { + "actorDid": { + "description": "The DID of the user who hit the rate limit.", + "type": "string", + "format": "did" + }, + "createdAt": { + "type": "string", + "format": "datetime" + }, + "endpoint": { + "description": "The NSID of the endpoint that was rate limited.", + "type": "string" + }, + "rev": { + "type": "string" + } + } + } + } +} diff --git a/lexicons/chat/bsky/moderation/updateActorAccess.json b/lexicons/chat/bsky/moderation/updateActorAccess.json new file mode 100644 index 0000000000..047d32e127 --- /dev/null +++ b/lexicons/chat/bsky/moderation/updateActorAccess.json @@ -0,0 +1,28 @@ +{ + "lexicon": 1, + "id": "chat.bsky.moderation.updateActorAccess", + "defs": { + "main": { + "type": "procedure", + "input": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["actor", "allowAccess"], + "properties": { + "actor": { + "type": "string", + "format": "did" + }, + "allowAccess": { + "type": "boolean" + }, + "ref": { + "type": "string" + } + } + } + } + } + } +} diff --git a/lexicons/chat/bsky/notification/defs.json b/lexicons/chat/bsky/notification/defs.json new file mode 100644 index 0000000000..56a510e022 --- /dev/null +++ b/lexicons/chat/bsky/notification/defs.json @@ -0,0 +1,33 @@ +{ + "lexicon": 1, + "id": "chat.bsky.notification.defs", + "defs": { + "preferences": { + "type": "object", + "required": ["chat", "chatRequest"], + "properties": { + "chat": { + "type": "ref", + "ref": "#chatPreference" + }, + "chatRequest": { + "type": "ref", + "ref": "#chatPreference" + } + } + }, + "chatPreference": { + "type": "object", + "required": ["include", "push"], + "properties": { + "include": { + "type": "string", + "knownValues": ["all", "follows"] + }, + "push": { + "type": "boolean" + } + } + } + } +} diff --git a/lexicons/chat/bsky/notification/getPreferences.json b/lexicons/chat/bsky/notification/getPreferences.json new file mode 100644 index 0000000000..86a915b5be --- /dev/null +++ b/lexicons/chat/bsky/notification/getPreferences.json @@ -0,0 +1,23 @@ +{ + "lexicon": 1, + "id": "chat.bsky.notification.getPreferences", + "defs": { + "main": { + "type": "query", + "description": "Get the requesting account's chat notification preferences. Defaults are returned for accounts that have not set any preferences. Requires auth.", + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["preferences"], + "properties": { + "preferences": { + "type": "ref", + "ref": "chat.bsky.notification.defs#preferences" + } + } + } + } + } + } +} diff --git a/lexicons/chat/bsky/notification/putPreferences.json b/lexicons/chat/bsky/notification/putPreferences.json new file mode 100644 index 0000000000..092e188fba --- /dev/null +++ b/lexicons/chat/bsky/notification/putPreferences.json @@ -0,0 +1,39 @@ +{ + "lexicon": 1, + "id": "chat.bsky.notification.putPreferences", + "defs": { + "main": { + "type": "procedure", + "description": "Set the requesting account's chat notification preferences. Only the provided preferences are updated; omitted preferences are left unchanged.", + "input": { + "encoding": "application/json", + "schema": { + "type": "object", + "properties": { + "chat": { + "type": "ref", + "ref": "chat.bsky.notification.defs#chatPreference" + }, + "chatRequest": { + "type": "ref", + "ref": "chat.bsky.notification.defs#chatPreference" + } + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["preferences"], + "properties": { + "preferences": { + "type": "ref", + "ref": "chat.bsky.notification.defs#preferences" + } + } + } + } + } + } +} diff --git a/lexicons/com/atproto/admin/defs.json b/lexicons/com/atproto/admin/defs.json new file mode 100644 index 0000000000..40b7954cc3 --- /dev/null +++ b/lexicons/com/atproto/admin/defs.json @@ -0,0 +1,117 @@ +{ + "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": "com.atproto.server.defs#inviteCode" + }, + "invites": { + "type": "array", + "items": { + "type": "ref", + "ref": "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": "#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" + } + } + } + } +} diff --git a/lexicons/com/atproto/admin/deleteAccount.json b/lexicons/com/atproto/admin/deleteAccount.json new file mode 100644 index 0000000000..78a39c53fe --- /dev/null +++ b/lexicons/com/atproto/admin/deleteAccount.json @@ -0,0 +1,23 @@ +{ + "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" + } + } + } + } + } + } +} diff --git a/lexicons/com/atproto/admin/disableAccountInvites.json b/lexicons/com/atproto/admin/disableAccountInvites.json new file mode 100644 index 0000000000..c083401070 --- /dev/null +++ b/lexicons/com/atproto/admin/disableAccountInvites.json @@ -0,0 +1,27 @@ +{ + "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." + } + } + } + } + } + } +} diff --git a/lexicons/com/atproto/admin/disableInviteCodes.json b/lexicons/com/atproto/admin/disableInviteCodes.json new file mode 100644 index 0000000000..a0a163d2ea --- /dev/null +++ b/lexicons/com/atproto/admin/disableInviteCodes.json @@ -0,0 +1,30 @@ +{ + "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" + } + } + } + } + } + } + } +} diff --git a/lexicons/com/atproto/admin/enableAccountInvites.json b/lexicons/com/atproto/admin/enableAccountInvites.json new file mode 100644 index 0000000000..d4df085561 --- /dev/null +++ b/lexicons/com/atproto/admin/enableAccountInvites.json @@ -0,0 +1,27 @@ +{ + "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." + } + } + } + } + } + } +} diff --git a/lexicons/com/atproto/admin/getAccountInfo.json b/lexicons/com/atproto/admin/getAccountInfo.json new file mode 100644 index 0000000000..106223824a --- /dev/null +++ b/lexicons/com/atproto/admin/getAccountInfo.json @@ -0,0 +1,27 @@ +{ + "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": "com.atproto.admin.defs#accountView" + } + } + } + } +} diff --git a/lexicons/com/atproto/admin/getAccountInfos.json b/lexicons/com/atproto/admin/getAccountInfos.json new file mode 100644 index 0000000000..a6303b66a7 --- /dev/null +++ b/lexicons/com/atproto/admin/getAccountInfos.json @@ -0,0 +1,39 @@ +{ + "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": "com.atproto.admin.defs#accountView" + } + } + } + } + } + } + } +} diff --git a/lexicons/com/atproto/admin/getInviteCodes.json b/lexicons/com/atproto/admin/getInviteCodes.json new file mode 100644 index 0000000000..d2ad5b66ae --- /dev/null +++ b/lexicons/com/atproto/admin/getInviteCodes.json @@ -0,0 +1,48 @@ +{ + "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": "com.atproto.server.defs#inviteCode" + } + } + } + } + } + } + } +} diff --git a/lexicons/com/atproto/admin/getSubjectStatus.json b/lexicons/com/atproto/admin/getSubjectStatus.json new file mode 100644 index 0000000000..9c72d7736d --- /dev/null +++ b/lexicons/com/atproto/admin/getSubjectStatus.json @@ -0,0 +1,52 @@ +{ + "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": [ + "com.atproto.admin.defs#repoRef", + "com.atproto.repo.strongRef", + "com.atproto.admin.defs#repoBlobRef" + ] + }, + "takedown": { + "type": "ref", + "ref": "com.atproto.admin.defs#statusAttr" + }, + "deactivated": { + "type": "ref", + "ref": "com.atproto.admin.defs#statusAttr" + } + } + } + } + } + } +} diff --git a/lexicons/com/atproto/admin/searchAccounts.json b/lexicons/com/atproto/admin/searchAccounts.json new file mode 100644 index 0000000000..b20fdf6687 --- /dev/null +++ b/lexicons/com/atproto/admin/searchAccounts.json @@ -0,0 +1,46 @@ +{ + "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": "com.atproto.admin.defs#accountView" + } + } + } + } + } + } + } +} diff --git a/lexicons/com/atproto/admin/sendEmail.json b/lexicons/com/atproto/admin/sendEmail.json new file mode 100644 index 0000000000..0ba4dd8f5c --- /dev/null +++ b/lexicons/com/atproto/admin/sendEmail.json @@ -0,0 +1,49 @@ +{ + "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" + } + } + } + } + } + } +} diff --git a/lexicons/com/atproto/admin/updateAccountEmail.json b/lexicons/com/atproto/admin/updateAccountEmail.json new file mode 100644 index 0000000000..fe5bc1c5d5 --- /dev/null +++ b/lexicons/com/atproto/admin/updateAccountEmail.json @@ -0,0 +1,27 @@ +{ + "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" + } + } + } + } + } + } +} diff --git a/lexicons/com/atproto/admin/updateAccountHandle.json b/lexicons/com/atproto/admin/updateAccountHandle.json new file mode 100644 index 0000000000..2ea0ac95e1 --- /dev/null +++ b/lexicons/com/atproto/admin/updateAccountHandle.json @@ -0,0 +1,27 @@ +{ + "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" + } + } + } + } + } + } +} diff --git a/lexicons/com/atproto/admin/updateAccountPassword.json b/lexicons/com/atproto/admin/updateAccountPassword.json new file mode 100644 index 0000000000..e4ebb5cf35 --- /dev/null +++ b/lexicons/com/atproto/admin/updateAccountPassword.json @@ -0,0 +1,26 @@ +{ + "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" + } + } + } + } + } + } +} diff --git a/lexicons/com/atproto/admin/updateAccountSigningKey.json b/lexicons/com/atproto/admin/updateAccountSigningKey.json new file mode 100644 index 0000000000..3b40f409cd --- /dev/null +++ b/lexicons/com/atproto/admin/updateAccountSigningKey.json @@ -0,0 +1,28 @@ +{ + "lexicon": 1, + "id": "com.atproto.admin.updateAccountSigningKey", + "defs": { + "main": { + "type": "procedure", + "description": "Administrative action to update an account's signing key in their Did document.", + "input": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["did", "signingKey"], + "properties": { + "did": { + "type": "string", + "format": "did" + }, + "signingKey": { + "type": "string", + "format": "did", + "description": "Did-key formatted public key" + } + } + } + } + } + } +} diff --git a/lexicons/com/atproto/admin/updateSubjectStatus.json b/lexicons/com/atproto/admin/updateSubjectStatus.json new file mode 100644 index 0000000000..799dee7b93 --- /dev/null +++ b/lexicons/com/atproto/admin/updateSubjectStatus.json @@ -0,0 +1,56 @@ +{ + "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": [ + "com.atproto.admin.defs#repoRef", + "com.atproto.repo.strongRef", + "com.atproto.admin.defs#repoBlobRef" + ] + }, + "takedown": { + "type": "ref", + "ref": "com.atproto.admin.defs#statusAttr" + }, + "deactivated": { + "type": "ref", + "ref": "com.atproto.admin.defs#statusAttr" + } + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["subject"], + "properties": { + "subject": { + "type": "union", + "refs": [ + "com.atproto.admin.defs#repoRef", + "com.atproto.repo.strongRef", + "com.atproto.admin.defs#repoBlobRef" + ] + }, + "takedown": { + "type": "ref", + "ref": "com.atproto.admin.defs#statusAttr" + } + } + } + } + } + } +} diff --git a/lexicons/com/atproto/identity/defs.json b/lexicons/com/atproto/identity/defs.json new file mode 100644 index 0000000000..aacdaa87b8 --- /dev/null +++ b/lexicons/com/atproto/identity/defs.json @@ -0,0 +1,25 @@ +{ + "lexicon": 1, + "id": "com.atproto.identity.defs", + "defs": { + "identityInfo": { + "type": "object", + "required": ["did", "handle", "didDoc"], + "properties": { + "did": { + "type": "string", + "format": "did" + }, + "handle": { + "type": "string", + "format": "handle", + "description": "The validated handle of the account; or 'handle.invalid' if the handle did not bi-directionally match the DID document." + }, + "didDoc": { + "type": "unknown", + "description": "The complete DID document for the identity." + } + } + } + } +} diff --git a/lexicons/com/atproto/identity/getRecommendedDidCredentials.json b/lexicons/com/atproto/identity/getRecommendedDidCredentials.json new file mode 100644 index 0000000000..35c3bc9365 --- /dev/null +++ b/lexicons/com/atproto/identity/getRecommendedDidCredentials.json @@ -0,0 +1,37 @@ +{ + "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" + } + } + } + } + } + } +} diff --git a/lexicons/com/atproto/identity/refreshIdentity.json b/lexicons/com/atproto/identity/refreshIdentity.json new file mode 100644 index 0000000000..4c56084b9e --- /dev/null +++ b/lexicons/com/atproto/identity/refreshIdentity.json @@ -0,0 +1,44 @@ +{ + "lexicon": 1, + "id": "com.atproto.identity.refreshIdentity", + "defs": { + "main": { + "type": "procedure", + "description": "Request that the server re-resolve an identity (DID and handle). The server may ignore this request, or require authentication, depending on the role, implementation, and policy of the server.", + "input": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["identifier"], + "properties": { + "identifier": { + "type": "string", + "format": "at-identifier" + } + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "ref", + "ref": "com.atproto.identity.defs#identityInfo" + } + }, + "errors": [ + { + "name": "HandleNotFound", + "description": "The resolution process confirmed that the handle does not resolve to any DID." + }, + { + "name": "DidNotFound", + "description": "The DID resolution process confirmed that there is no current DID." + }, + { + "name": "DidDeactivated", + "description": "The DID previously existed, but has been deactivated." + } + ] + } + } +} diff --git a/lexicons/com/atproto/identity/requestPlcOperationSignature.json b/lexicons/com/atproto/identity/requestPlcOperationSignature.json new file mode 100644 index 0000000000..4aa8b18fee --- /dev/null +++ b/lexicons/com/atproto/identity/requestPlcOperationSignature.json @@ -0,0 +1,10 @@ +{ + "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." + } + } +} diff --git a/lexicons/com/atproto/identity/resolveDid.json b/lexicons/com/atproto/identity/resolveDid.json new file mode 100644 index 0000000000..24c129a333 --- /dev/null +++ b/lexicons/com/atproto/identity/resolveDid.json @@ -0,0 +1,44 @@ +{ + "lexicon": 1, + "id": "com.atproto.identity.resolveDid", + "defs": { + "main": { + "type": "query", + "description": "Resolves DID to DID document. Does not bi-directionally verify handle.", + "parameters": { + "type": "params", + "required": ["did"], + "properties": { + "did": { + "type": "string", + "format": "did", + "description": "DID to resolve." + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["didDoc"], + "properties": { + "didDoc": { + "type": "unknown", + "description": "The complete DID document for the identity." + } + } + } + }, + "errors": [ + { + "name": "DidNotFound", + "description": "The DID resolution process confirmed that there is no current DID." + }, + { + "name": "DidDeactivated", + "description": "The DID previously existed, but has been deactivated." + } + ] + } + } +} diff --git a/lexicons/com/atproto/identity/resolveHandle.json b/lexicons/com/atproto/identity/resolveHandle.json new file mode 100644 index 0000000000..63e4e52465 --- /dev/null +++ b/lexicons/com/atproto/identity/resolveHandle.json @@ -0,0 +1,40 @@ +{ + "lexicon": 1, + "id": "com.atproto.identity.resolveHandle", + "defs": { + "main": { + "type": "query", + "description": "Resolves an atproto handle (hostname) to a DID. Does not necessarily bi-directionally verify against the the DID document.", + "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" + } + } + } + }, + "errors": [ + { + "name": "HandleNotFound", + "description": "The resolution process confirmed that the handle does not resolve to any DID." + } + ] + } + } +} diff --git a/lexicons/com/atproto/identity/resolveIdentity.json b/lexicons/com/atproto/identity/resolveIdentity.json new file mode 100644 index 0000000000..fe33441c4e --- /dev/null +++ b/lexicons/com/atproto/identity/resolveIdentity.json @@ -0,0 +1,42 @@ +{ + "lexicon": 1, + "id": "com.atproto.identity.resolveIdentity", + "defs": { + "main": { + "type": "query", + "description": "Resolves an identity (DID or Handle) to a full identity (DID document and verified handle).", + "parameters": { + "type": "params", + "required": ["identifier"], + "properties": { + "identifier": { + "type": "string", + "format": "at-identifier", + "description": "Handle or DID to resolve." + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "ref", + "ref": "com.atproto.identity.defs#identityInfo" + } + }, + "errors": [ + { + "name": "HandleNotFound", + "description": "The resolution process confirmed that the handle does not resolve to any DID." + }, + { + "name": "DidNotFound", + "description": "The DID resolution process confirmed that there is no current DID." + }, + { + "name": "DidDeactivated", + "description": "The DID previously existed, but has been deactivated." + } + ] + } + } +} diff --git a/lexicons/com/atproto/identity/signPlcOperation.json b/lexicons/com/atproto/identity/signPlcOperation.json new file mode 100644 index 0000000000..b5c8f67539 --- /dev/null +++ b/lexicons/com/atproto/identity/signPlcOperation.json @@ -0,0 +1,53 @@ +{ + "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." + } + } + } + } + } + } +} diff --git a/lexicons/com/atproto/identity/submitPlcOperation.json b/lexicons/com/atproto/identity/submitPlcOperation.json new file mode 100644 index 0000000000..ff4025a0f1 --- /dev/null +++ b/lexicons/com/atproto/identity/submitPlcOperation.json @@ -0,0 +1,22 @@ +{ + "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" + } + } + } + } + } + } +} diff --git a/lexicons/com/atproto/identity/updateHandle.json b/lexicons/com/atproto/identity/updateHandle.json new file mode 100644 index 0000000000..9bb5c347d3 --- /dev/null +++ b/lexicons/com/atproto/identity/updateHandle.json @@ -0,0 +1,24 @@ +{ + "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." + } + } + } + } + } + } +} diff --git a/lexicons/com/atproto/label/defs.json b/lexicons/com/atproto/label/defs.json new file mode 100644 index 0000000000..0da40dff6b --- /dev/null +++ b/lexicons/com/atproto/label/defs.json @@ -0,0 +1,159 @@ +{ + "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": "#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": "#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", + "!warn", + "!no-unauthenticated", + "porn", + "sexual", + "nudity", + "graphic-media", + "bot" + ] + } + } +} diff --git a/lexicons/com/atproto/label/queryLabels.json b/lexicons/com/atproto/label/queryLabels.json new file mode 100644 index 0000000000..6cb2be2c06 --- /dev/null +++ b/lexicons/com/atproto/label/queryLabels.json @@ -0,0 +1,59 @@ +{ + "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": "com.atproto.label.defs#label" + } + } + } + } + } + } + } +} diff --git a/lexicons/com/atproto/label/subscribeLabels.json b/lexicons/com/atproto/label/subscribeLabels.json new file mode 100644 index 0000000000..a95306c589 --- /dev/null +++ b/lexicons/com/atproto/label/subscribeLabels.json @@ -0,0 +1,59 @@ +{ + "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": ["#labels", "#info"] + } + }, + "errors": [ + { + "name": "FutureCursor" + } + ] + }, + "labels": { + "type": "object", + "required": ["seq", "labels"], + "properties": { + "seq": { + "type": "integer" + }, + "labels": { + "type": "array", + "items": { + "type": "ref", + "ref": "com.atproto.label.defs#label" + } + } + } + }, + "info": { + "type": "object", + "required": ["name"], + "properties": { + "name": { + "type": "string", + "knownValues": ["OutdatedCursor"] + }, + "message": { + "type": "string" + } + } + } + } +} diff --git a/lexicons/com/atproto/lexicon/resolveLexicon.json b/lexicons/com/atproto/lexicon/resolveLexicon.json new file mode 100644 index 0000000000..bf836d23b3 --- /dev/null +++ b/lexicons/com/atproto/lexicon/resolveLexicon.json @@ -0,0 +1,51 @@ +{ + "lexicon": 1, + "id": "com.atproto.lexicon.resolveLexicon", + "defs": { + "main": { + "type": "query", + "description": "Resolves an atproto lexicon (NSID) to a schema.", + "parameters": { + "type": "params", + "properties": { + "nsid": { + "format": "nsid", + "type": "string", + "description": "The lexicon NSID to resolve." + } + }, + "required": ["nsid"] + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "properties": { + "cid": { + "type": "string", + "format": "cid", + "description": "The CID of the lexicon schema record." + }, + "schema": { + "type": "ref", + "ref": "com.atproto.lexicon.schema#main", + "description": "The resolved lexicon schema record." + }, + "uri": { + "type": "string", + "format": "at-uri", + "description": "The AT-URI of the lexicon schema record." + } + }, + "required": ["uri", "cid", "schema"] + } + }, + "errors": [ + { + "description": "No lexicon was resolved for the NSID.", + "name": "LexiconNotFound" + } + ] + } + } +} diff --git a/lexicons/com/atproto/lexicon/schema.json b/lexicons/com/atproto/lexicon/schema.json new file mode 100644 index 0000000000..e79337ba6d --- /dev/null +++ b/lexicons/com/atproto/lexicon/schema.json @@ -0,0 +1,21 @@ +{ + "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." + } + } + } + } + } +} diff --git a/lexicons/com/atproto/moderation/createReport.json b/lexicons/com/atproto/moderation/createReport.json new file mode 100644 index 0000000000..deff33e6bb --- /dev/null +++ b/lexicons/com/atproto/moderation/createReport.json @@ -0,0 +1,98 @@ +{ + "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": "com.atproto.moderation.defs#reasonType" + }, + "reason": { + "type": "string", + "maxGraphemes": 2000, + "maxLength": 20000, + "description": "Additional context about the content and violation." + }, + "subject": { + "type": "union", + "refs": [ + "com.atproto.admin.defs#repoRef", + "com.atproto.repo.strongRef" + ] + }, + "modTool": { + "type": "ref", + "ref": "#modTool" + } + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": [ + "id", + "reasonType", + "subject", + "reportedBy", + "createdAt" + ], + "properties": { + "id": { + "type": "integer" + }, + "reasonType": { + "type": "ref", + "ref": "com.atproto.moderation.defs#reasonType" + }, + "reason": { + "type": "string", + "maxGraphemes": 2000, + "maxLength": 20000 + }, + "subject": { + "type": "union", + "refs": [ + "com.atproto.admin.defs#repoRef", + "com.atproto.repo.strongRef" + ] + }, + "reportedBy": { + "type": "string", + "format": "did" + }, + "createdAt": { + "type": "string", + "format": "datetime" + } + } + } + } + }, + "modTool": { + "type": "object", + "description": "Moderation tool information for tracing the source of the action", + "required": ["name"], + "properties": { + "name": { + "type": "string", + "description": "Name/identifier of the source (e.g., 'bsky-app/android', 'bsky-web/chrome')" + }, + "meta": { + "type": "unknown", + "description": "Additional arbitrary metadata about the source" + } + } + } + } +} diff --git a/lexicons/com/atproto/moderation/defs.json b/lexicons/com/atproto/moderation/defs.json new file mode 100644 index 0000000000..b3f310fed5 --- /dev/null +++ b/lexicons/com/atproto/moderation/defs.json @@ -0,0 +1,91 @@ +{ + "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", + "tools.ozone.report.defs#reasonAppeal", + "tools.ozone.report.defs#reasonOther", + "tools.ozone.report.defs#reasonViolenceAnimal", + "tools.ozone.report.defs#reasonViolenceThreats", + "tools.ozone.report.defs#reasonViolenceGraphicContent", + "tools.ozone.report.defs#reasonViolenceGlorification", + "tools.ozone.report.defs#reasonViolenceExtremistContent", + "tools.ozone.report.defs#reasonViolenceTrafficking", + "tools.ozone.report.defs#reasonViolenceOther", + "tools.ozone.report.defs#reasonSexualAbuseContent", + "tools.ozone.report.defs#reasonSexualNCII", + "tools.ozone.report.defs#reasonSexualDeepfake", + "tools.ozone.report.defs#reasonSexualAnimal", + "tools.ozone.report.defs#reasonSexualUnlabeled", + "tools.ozone.report.defs#reasonSexualOther", + "tools.ozone.report.defs#reasonChildSafetyCSAM", + "tools.ozone.report.defs#reasonChildSafetyGroom", + "tools.ozone.report.defs#reasonChildSafetyPrivacy", + "tools.ozone.report.defs#reasonChildSafetyHarassment", + "tools.ozone.report.defs#reasonChildSafetyOther", + "tools.ozone.report.defs#reasonHarassmentTroll", + "tools.ozone.report.defs#reasonHarassmentTargeted", + "tools.ozone.report.defs#reasonHarassmentHateSpeech", + "tools.ozone.report.defs#reasonHarassmentDoxxing", + "tools.ozone.report.defs#reasonHarassmentOther", + "tools.ozone.report.defs#reasonMisleadingBot", + "tools.ozone.report.defs#reasonMisleadingImpersonation", + "tools.ozone.report.defs#reasonMisleadingSpam", + "tools.ozone.report.defs#reasonMisleadingScam", + "tools.ozone.report.defs#reasonMisleadingElections", + "tools.ozone.report.defs#reasonMisleadingOther", + "tools.ozone.report.defs#reasonRuleSiteSecurity", + "tools.ozone.report.defs#reasonRuleProhibitedSales", + "tools.ozone.report.defs#reasonRuleBanEvasion", + "tools.ozone.report.defs#reasonRuleOther", + "tools.ozone.report.defs#reasonSelfHarmContent", + "tools.ozone.report.defs#reasonSelfHarmED", + "tools.ozone.report.defs#reasonSelfHarmStunts", + "tools.ozone.report.defs#reasonSelfHarmSubstances", + "tools.ozone.report.defs#reasonSelfHarmOther" + ] + }, + "reasonSpam": { + "type": "token", + "description": "Spam: frequent unwanted promotion, replies, mentions. Prefer new lexicon definition `tools.ozone.report.defs#reasonMisleadingSpam`." + }, + "reasonViolation": { + "type": "token", + "description": "Direct violation of server rules, laws, terms of service. Prefer new lexicon definition `tools.ozone.report.defs#reasonRuleOther`." + }, + "reasonMisleading": { + "type": "token", + "description": "Misleading identity, affiliation, or content. Prefer new lexicon definition `tools.ozone.report.defs#reasonMisleadingOther`." + }, + "reasonSexual": { + "type": "token", + "description": "Unwanted or mislabeled sexual content. Prefer new lexicon definition `tools.ozone.report.defs#reasonSexualUnlabeled`." + }, + "reasonRude": { + "type": "token", + "description": "Rude, harassing, explicit, or otherwise unwelcoming behavior. Prefer new lexicon definition `tools.ozone.report.defs#reasonHarassmentOther`." + }, + "reasonOther": { + "type": "token", + "description": "Reports not falling under another report category. Prefer new lexicon definition `tools.ozone.report.defs#reasonOther`." + }, + "reasonAppeal": { + "type": "token", + "description": "Appeal a previously taken moderation action" + }, + "subjectType": { + "type": "string", + "description": "Tag describing a type of subject that might be reported.", + "knownValues": ["account", "record", "chat"] + } + } +} diff --git a/lexicons/com/atproto/repo/applyWrites.json b/lexicons/com/atproto/repo/applyWrites.json new file mode 100644 index 0000000000..2754aa9262 --- /dev/null +++ b/lexicons/com/atproto/repo/applyWrites.json @@ -0,0 +1,162 @@ +{ + "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": ["#create", "#update", "#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": "com.atproto.repo.defs#commitMeta" + }, + "results": { + "type": "array", + "items": { + "type": "union", + "refs": ["#createResult", "#updateResult", "#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, + "format": "record-key", + "description": "NOTE: maxLength is redundant with record-key format. Keeping it temporarily to ensure backwards compatibility." + }, + "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", + "format": "record-key" + }, + "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", + "format": "record-key" + } + } + }, + "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": {} + } + } +} diff --git a/lexicons/com/atproto/repo/createRecord.json b/lexicons/com/atproto/repo/createRecord.json new file mode 100644 index 0000000000..fbbe97ff2f --- /dev/null +++ b/lexicons/com/atproto/repo/createRecord.json @@ -0,0 +1,79 @@ +{ + "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", + "format": "record-key", + "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": "com.atproto.repo.defs#commitMeta" + }, + "validationStatus": { + "type": "string", + "knownValues": ["valid", "unknown"] + } + } + } + }, + "errors": [ + { + "name": "InvalidSwap", + "description": "Indicates that 'swapCommit' didn't match current repo commit." + } + ] + } + } +} diff --git a/lexicons/com/atproto/repo/defs.json b/lexicons/com/atproto/repo/defs.json new file mode 100644 index 0000000000..026190b806 --- /dev/null +++ b/lexicons/com/atproto/repo/defs.json @@ -0,0 +1,20 @@ +{ + "lexicon": 1, + "id": "com.atproto.repo.defs", + "defs": { + "commitMeta": { + "type": "object", + "required": ["cid", "rev"], + "properties": { + "cid": { + "type": "string", + "format": "cid" + }, + "rev": { + "type": "string", + "format": "tid" + } + } + } + } +} diff --git a/lexicons/com/atproto/repo/deleteRecord.json b/lexicons/com/atproto/repo/deleteRecord.json new file mode 100644 index 0000000000..140e5144a6 --- /dev/null +++ b/lexicons/com/atproto/repo/deleteRecord.json @@ -0,0 +1,61 @@ +{ + "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", + "format": "record-key", + "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": "com.atproto.repo.defs#commitMeta" + } + } + } + }, + "errors": [ + { + "name": "InvalidSwap" + } + ] + } + } +} diff --git a/lexicons/com/atproto/repo/describeRepo.json b/lexicons/com/atproto/repo/describeRepo.json new file mode 100644 index 0000000000..b1def1a9da --- /dev/null +++ b/lexicons/com/atproto/repo/describeRepo.json @@ -0,0 +1,60 @@ +{ + "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)" + } + } + } + } + } + } +} diff --git a/lexicons/com/atproto/repo/getRecord.json b/lexicons/com/atproto/repo/getRecord.json new file mode 100644 index 0000000000..5f3311100f --- /dev/null +++ b/lexicons/com/atproto/repo/getRecord.json @@ -0,0 +1,61 @@ +{ + "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.", + "format": "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" + } + ] + } + } +} diff --git a/lexicons/com/atproto/repo/importRepo.json b/lexicons/com/atproto/repo/importRepo.json new file mode 100644 index 0000000000..fc850b1a2b --- /dev/null +++ b/lexicons/com/atproto/repo/importRepo.json @@ -0,0 +1,13 @@ +{ + "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" + } + } + } +} diff --git a/lexicons/com/atproto/repo/listMissingBlobs.json b/lexicons/com/atproto/repo/listMissingBlobs.json new file mode 100644 index 0000000000..e9eb869c82 --- /dev/null +++ b/lexicons/com/atproto/repo/listMissingBlobs.json @@ -0,0 +1,57 @@ +{ + "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": "#recordBlob" + } + } + } + } + } + }, + "recordBlob": { + "type": "object", + "required": ["cid", "recordUri"], + "properties": { + "cid": { + "type": "string", + "format": "cid" + }, + "recordUri": { + "type": "string", + "format": "at-uri" + } + } + } + } +} diff --git a/lexicons/com/atproto/repo/listRecords.json b/lexicons/com/atproto/repo/listRecords.json new file mode 100644 index 0000000000..3fac17ac98 --- /dev/null +++ b/lexicons/com/atproto/repo/listRecords.json @@ -0,0 +1,76 @@ +{ + "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" + }, + "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": "#record" + } + } + } + } + } + }, + "record": { + "type": "object", + "required": ["uri", "cid", "value"], + "properties": { + "uri": { + "type": "string", + "format": "at-uri" + }, + "cid": { + "type": "string", + "format": "cid" + }, + "value": { + "type": "unknown" + } + } + } + } +} diff --git a/lexicons/com/atproto/repo/putRecord.json b/lexicons/com/atproto/repo/putRecord.json new file mode 100644 index 0000000000..c8f3e1f48b --- /dev/null +++ b/lexicons/com/atproto/repo/putRecord.json @@ -0,0 +1,84 @@ +{ + "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", + "format": "record-key", + "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": "com.atproto.repo.defs#commitMeta" + }, + "validationStatus": { + "type": "string", + "knownValues": ["valid", "unknown"] + } + } + } + }, + "errors": [ + { + "name": "InvalidSwap" + } + ] + } + } +} diff --git a/lexicons/com/atproto/repo/strongRef.json b/lexicons/com/atproto/repo/strongRef.json new file mode 100644 index 0000000000..14cd5f920f --- /dev/null +++ b/lexicons/com/atproto/repo/strongRef.json @@ -0,0 +1,21 @@ +{ + "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" + } + } + } + } +} diff --git a/lexicons/com/atproto/repo/uploadBlob.json b/lexicons/com/atproto/repo/uploadBlob.json new file mode 100644 index 0000000000..4ebb573fad --- /dev/null +++ b/lexicons/com/atproto/repo/uploadBlob.json @@ -0,0 +1,25 @@ +{ + "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" + } + } + } + } + } + } +} diff --git a/lexicons/com/atproto/server/activateAccount.json b/lexicons/com/atproto/server/activateAccount.json new file mode 100644 index 0000000000..e06935fcd0 --- /dev/null +++ b/lexicons/com/atproto/server/activateAccount.json @@ -0,0 +1,10 @@ +{ + "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." + } + } +} diff --git a/lexicons/com/atproto/server/checkAccountStatus.json b/lexicons/com/atproto/server/checkAccountStatus.json new file mode 100644 index 0000000000..8047bc0626 --- /dev/null +++ b/lexicons/com/atproto/server/checkAccountStatus.json @@ -0,0 +1,57 @@ +{ + "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" + } + } + } + } + } + } +} diff --git a/lexicons/com/atproto/server/confirmEmail.json b/lexicons/com/atproto/server/confirmEmail.json new file mode 100644 index 0000000000..a4fb0f3ec1 --- /dev/null +++ b/lexicons/com/atproto/server/confirmEmail.json @@ -0,0 +1,39 @@ +{ + "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" + } + ] + } + } +} diff --git a/lexicons/com/atproto/server/createAccount.json b/lexicons/com/atproto/server/createAccount.json new file mode 100644 index 0000000000..60b5022317 --- /dev/null +++ b/lexicons/com/atproto/server/createAccount.json @@ -0,0 +1,105 @@ +{ + "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" + } + ] + } + } +} diff --git a/lexicons/com/atproto/server/createAppPassword.json b/lexicons/com/atproto/server/createAppPassword.json new file mode 100644 index 0000000000..65fdcf6281 --- /dev/null +++ b/lexicons/com/atproto/server/createAppPassword.json @@ -0,0 +1,58 @@ +{ + "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": "#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" + } + } + } + } +} diff --git a/lexicons/com/atproto/server/createInviteCode.json b/lexicons/com/atproto/server/createInviteCode.json new file mode 100644 index 0000000000..4801ba9bcf --- /dev/null +++ b/lexicons/com/atproto/server/createInviteCode.json @@ -0,0 +1,38 @@ +{ + "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" + } + } + } + } + } + } +} diff --git a/lexicons/com/atproto/server/createInviteCodes.json b/lexicons/com/atproto/server/createInviteCodes.json new file mode 100644 index 0000000000..145f8dbd49 --- /dev/null +++ b/lexicons/com/atproto/server/createInviteCodes.json @@ -0,0 +1,64 @@ +{ + "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": "#accountCodes" + } + } + } + } + } + }, + "accountCodes": { + "type": "object", + "required": ["account", "codes"], + "properties": { + "account": { + "type": "string" + }, + "codes": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + } +} diff --git a/lexicons/com/atproto/server/createSession.json b/lexicons/com/atproto/server/createSession.json new file mode 100644 index 0000000000..d52c4eea20 --- /dev/null +++ b/lexicons/com/atproto/server/createSession.json @@ -0,0 +1,84 @@ +{ + "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" + } + ] + } + } +} diff --git a/lexicons/com/atproto/server/deactivateAccount.json b/lexicons/com/atproto/server/deactivateAccount.json new file mode 100644 index 0000000000..698fccf202 --- /dev/null +++ b/lexicons/com/atproto/server/deactivateAccount.json @@ -0,0 +1,23 @@ +{ + "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." + } + } + } + } + } + } +} diff --git a/lexicons/com/atproto/server/defs.json b/lexicons/com/atproto/server/defs.json new file mode 100644 index 0000000000..6c1441cb70 --- /dev/null +++ b/lexicons/com/atproto/server/defs.json @@ -0,0 +1,60 @@ +{ + "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": "#inviteCodeUse" + } + } + } + }, + "inviteCodeUse": { + "type": "object", + "required": ["usedBy", "usedAt"], + "properties": { + "usedBy": { + "type": "string", + "format": "did" + }, + "usedAt": { + "type": "string", + "format": "datetime" + } + } + } + } +} diff --git a/lexicons/com/atproto/server/deleteAccount.json b/lexicons/com/atproto/server/deleteAccount.json new file mode 100644 index 0000000000..348575003c --- /dev/null +++ b/lexicons/com/atproto/server/deleteAccount.json @@ -0,0 +1,37 @@ +{ + "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" + } + ] + } + } +} diff --git a/lexicons/com/atproto/server/deleteSession.json b/lexicons/com/atproto/server/deleteSession.json new file mode 100644 index 0000000000..ccc6ee9d58 --- /dev/null +++ b/lexicons/com/atproto/server/deleteSession.json @@ -0,0 +1,18 @@ +{ + "lexicon": 1, + "id": "com.atproto.server.deleteSession", + "defs": { + "main": { + "type": "procedure", + "description": "Delete the current session. Requires auth using the 'refreshJwt' (not the 'accessJwt').", + "errors": [ + { + "name": "InvalidToken" + }, + { + "name": "ExpiredToken" + } + ] + } + } +} diff --git a/lexicons/com/atproto/server/describeServer.json b/lexicons/com/atproto/server/describeServer.json new file mode 100644 index 0000000000..6c27d7116c --- /dev/null +++ b/lexicons/com/atproto/server/describeServer.json @@ -0,0 +1,69 @@ +{ + "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": "#links" + }, + "contact": { + "type": "ref", + "description": "Contact information", + "ref": "#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" + } + } + } + } +} diff --git a/lexicons/com/atproto/server/getAccountInviteCodes.json b/lexicons/com/atproto/server/getAccountInviteCodes.json new file mode 100644 index 0000000000..39934e8402 --- /dev/null +++ b/lexicons/com/atproto/server/getAccountInviteCodes.json @@ -0,0 +1,45 @@ +{ + "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": "com.atproto.server.defs#inviteCode" + } + } + } + } + }, + "errors": [ + { + "name": "DuplicateCreate" + } + ] + } + } +} diff --git a/lexicons/com/atproto/server/getServiceAuth.json b/lexicons/com/atproto/server/getServiceAuth.json new file mode 100644 index 0000000000..e0c694767a --- /dev/null +++ b/lexicons/com/atproto/server/getServiceAuth.json @@ -0,0 +1,48 @@ +{ + "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", + "maxLength": 2048, + "description": "The DID or `did#serviceId` reference 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." + } + ] + } + } +} diff --git a/lexicons/com/atproto/server/getSession.json b/lexicons/com/atproto/server/getSession.json new file mode 100644 index 0000000000..3dd1c547df --- /dev/null +++ b/lexicons/com/atproto/server/getSession.json @@ -0,0 +1,47 @@ +{ + "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" + }, + "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"] + } + } + } + } + } + } +} diff --git a/lexicons/com/atproto/server/listAppPasswords.json b/lexicons/com/atproto/server/listAppPasswords.json new file mode 100644 index 0000000000..84475c3d1c --- /dev/null +++ b/lexicons/com/atproto/server/listAppPasswords.json @@ -0,0 +1,47 @@ +{ + "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": "#appPassword" + } + } + } + } + }, + "errors": [ + { + "name": "AccountTakedown" + } + ] + }, + "appPassword": { + "type": "object", + "required": ["name", "createdAt"], + "properties": { + "name": { + "type": "string" + }, + "createdAt": { + "type": "string", + "format": "datetime" + }, + "privileged": { + "type": "boolean" + } + } + } + } +} diff --git a/lexicons/com/atproto/server/refreshSession.json b/lexicons/com/atproto/server/refreshSession.json new file mode 100644 index 0000000000..bac84730b2 --- /dev/null +++ b/lexicons/com/atproto/server/refreshSession.json @@ -0,0 +1,64 @@ +{ + "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" + }, + "email": { + "type": "string" + }, + "emailConfirmed": { + "type": "boolean" + }, + "emailAuthFactor": { + "type": "boolean" + }, + "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" + }, + { + "name": "InvalidToken" + }, + { + "name": "ExpiredToken" + } + ] + } + } +} diff --git a/lexicons/com/atproto/server/requestAccountDelete.json b/lexicons/com/atproto/server/requestAccountDelete.json new file mode 100644 index 0000000000..aaac0b70ec --- /dev/null +++ b/lexicons/com/atproto/server/requestAccountDelete.json @@ -0,0 +1,10 @@ +{ + "lexicon": 1, + "id": "com.atproto.server.requestAccountDelete", + "defs": { + "main": { + "type": "procedure", + "description": "Initiate a user account deletion via email." + } + } +} diff --git a/lexicons/com/atproto/server/requestEmailConfirmation.json b/lexicons/com/atproto/server/requestEmailConfirmation.json new file mode 100644 index 0000000000..0020ed3160 --- /dev/null +++ b/lexicons/com/atproto/server/requestEmailConfirmation.json @@ -0,0 +1,10 @@ +{ + "lexicon": 1, + "id": "com.atproto.server.requestEmailConfirmation", + "defs": { + "main": { + "type": "procedure", + "description": "Request an email with a code to confirm ownership of email." + } + } +} diff --git a/lexicons/com/atproto/server/requestEmailUpdate.json b/lexicons/com/atproto/server/requestEmailUpdate.json new file mode 100644 index 0000000000..9ead9b7edb --- /dev/null +++ b/lexicons/com/atproto/server/requestEmailUpdate.json @@ -0,0 +1,22 @@ +{ + "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" + } + } + } + } + } + } +} diff --git a/lexicons/com/atproto/server/requestPasswordReset.json b/lexicons/com/atproto/server/requestPasswordReset.json new file mode 100644 index 0000000000..8a1e82c35b --- /dev/null +++ b/lexicons/com/atproto/server/requestPasswordReset.json @@ -0,0 +1,22 @@ +{ + "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" + } + } + } + } + } + } +} diff --git a/lexicons/com/atproto/server/reserveSigningKey.json b/lexicons/com/atproto/server/reserveSigningKey.json new file mode 100644 index 0000000000..a33e1ede68 --- /dev/null +++ b/lexicons/com/atproto/server/reserveSigningKey.json @@ -0,0 +1,36 @@ +{ + "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." + } + } + } + } + } + } +} diff --git a/lexicons/com/atproto/server/resetPassword.json b/lexicons/com/atproto/server/resetPassword.json new file mode 100644 index 0000000000..e8d6c5a938 --- /dev/null +++ b/lexicons/com/atproto/server/resetPassword.json @@ -0,0 +1,33 @@ +{ + "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" + } + ] + } + } +} diff --git a/lexicons/com/atproto/server/revokeAppPassword.json b/lexicons/com/atproto/server/revokeAppPassword.json new file mode 100644 index 0000000000..a6163336f1 --- /dev/null +++ b/lexicons/com/atproto/server/revokeAppPassword.json @@ -0,0 +1,22 @@ +{ + "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" + } + } + } + } + } + } +} diff --git a/lexicons/com/atproto/server/updateEmail.json b/lexicons/com/atproto/server/updateEmail.json new file mode 100644 index 0000000000..91267af0b1 --- /dev/null +++ b/lexicons/com/atproto/server/updateEmail.json @@ -0,0 +1,40 @@ +{ + "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" + } + ] + } + } +} diff --git a/lexicons/com/atproto/sync/defs.json b/lexicons/com/atproto/sync/defs.json new file mode 100644 index 0000000000..44261ac556 --- /dev/null +++ b/lexicons/com/atproto/sync/defs.json @@ -0,0 +1,10 @@ +{ + "lexicon": 1, + "id": "com.atproto.sync.defs", + "defs": { + "hostStatus": { + "type": "string", + "knownValues": ["active", "idle", "offline", "throttled", "banned"] + } + } +} diff --git a/lexicons/com/atproto/sync/getBlob.json b/lexicons/com/atproto/sync/getBlob.json new file mode 100644 index 0000000000..e87c8e01ba --- /dev/null +++ b/lexicons/com/atproto/sync/getBlob.json @@ -0,0 +1,46 @@ +{ + "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" + } + ] + } + } +} diff --git a/lexicons/com/atproto/sync/getBlocks.json b/lexicons/com/atproto/sync/getBlocks.json new file mode 100644 index 0000000000..2336f3d561 --- /dev/null +++ b/lexicons/com/atproto/sync/getBlocks.json @@ -0,0 +1,48 @@ +{ + "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" + } + ] + } + } +} diff --git a/lexicons/com/atproto/sync/getCheckout.json b/lexicons/com/atproto/sync/getCheckout.json new file mode 100644 index 0000000000..b3fb375e5d --- /dev/null +++ b/lexicons/com/atproto/sync/getCheckout.json @@ -0,0 +1,24 @@ +{ + "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" + } + } + } +} diff --git a/lexicons/com/atproto/sync/getHead.json b/lexicons/com/atproto/sync/getHead.json new file mode 100644 index 0000000000..65312e5a64 --- /dev/null +++ b/lexicons/com/atproto/sync/getHead.json @@ -0,0 +1,39 @@ +{ + "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" + } + ] + } + } +} diff --git a/lexicons/com/atproto/sync/getHostStatus.json b/lexicons/com/atproto/sync/getHostStatus.json new file mode 100644 index 0000000000..18ae87e8dc --- /dev/null +++ b/lexicons/com/atproto/sync/getHostStatus.json @@ -0,0 +1,49 @@ +{ + "lexicon": 1, + "id": "com.atproto.sync.getHostStatus", + "defs": { + "main": { + "type": "query", + "description": "Returns information about a specified upstream host, as consumed by the server. Implemented by relays.", + "parameters": { + "type": "params", + "required": ["hostname"], + "properties": { + "hostname": { + "type": "string", + "description": "Hostname of the host (eg, PDS or relay) being queried." + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["hostname"], + "properties": { + "hostname": { + "type": "string" + }, + "seq": { + "type": "integer", + "description": "Recent repo stream event sequence number. May be delayed from actual stream processing (eg, persisted cursor not in-memory cursor)." + }, + "accountCount": { + "type": "integer", + "description": "Number of accounts on the server which are associated with the upstream host. Note that the upstream may actually have more accounts." + }, + "status": { + "type": "ref", + "ref": "com.atproto.sync.defs#hostStatus" + } + } + } + }, + "errors": [ + { + "name": "HostNotFound" + } + ] + } + } +} diff --git a/lexicons/com/atproto/sync/getLatestCommit.json b/lexicons/com/atproto/sync/getLatestCommit.json new file mode 100644 index 0000000000..fbe2907b6a --- /dev/null +++ b/lexicons/com/atproto/sync/getLatestCommit.json @@ -0,0 +1,52 @@ +{ + "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", + "format": "tid" + } + } + } + }, + "errors": [ + { + "name": "RepoNotFound" + }, + { + "name": "RepoTakendown" + }, + { + "name": "RepoSuspended" + }, + { + "name": "RepoDeactivated" + } + ] + } + } +} diff --git a/lexicons/com/atproto/sync/getRecord.json b/lexicons/com/atproto/sync/getRecord.json new file mode 100644 index 0000000000..aa3a3b6389 --- /dev/null +++ b/lexicons/com/atproto/sync/getRecord.json @@ -0,0 +1,50 @@ +{ + "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", + "format": "record-key" + } + } + }, + "output": { + "encoding": "application/vnd.ipld.car" + }, + "errors": [ + { + "name": "RecordNotFound" + }, + { + "name": "RepoNotFound" + }, + { + "name": "RepoTakendown" + }, + { + "name": "RepoSuspended" + }, + { + "name": "RepoDeactivated" + } + ] + } + } +} diff --git a/lexicons/com/atproto/sync/getRepo.json b/lexicons/com/atproto/sync/getRepo.json new file mode 100644 index 0000000000..5e600d0ad9 --- /dev/null +++ b/lexicons/com/atproto/sync/getRepo.json @@ -0,0 +1,43 @@ +{ + "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", + "format": "tid", + "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" + } + ] + } + } +} diff --git a/lexicons/com/atproto/sync/getRepoStatus.json b/lexicons/com/atproto/sync/getRepoStatus.json new file mode 100644 index 0000000000..4c49c4072d --- /dev/null +++ b/lexicons/com/atproto/sync/getRepoStatus.json @@ -0,0 +1,59 @@ +{ + "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", + "deleted", + "deactivated", + "desynchronized", + "throttled" + ] + }, + "rev": { + "type": "string", + "format": "tid", + "description": "Optional field, the current rev of the repo, if active=true" + } + } + } + }, + "errors": [ + { + "name": "RepoNotFound" + } + ] + } + } +} diff --git a/lexicons/com/atproto/sync/listBlobs.json b/lexicons/com/atproto/sync/listBlobs.json new file mode 100644 index 0000000000..bc92ef06bb --- /dev/null +++ b/lexicons/com/atproto/sync/listBlobs.json @@ -0,0 +1,68 @@ +{ + "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", + "format": "tid", + "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" + } + ] + } + } +} diff --git a/lexicons/com/atproto/sync/listHosts.json b/lexicons/com/atproto/sync/listHosts.json new file mode 100644 index 0000000000..14807fa549 --- /dev/null +++ b/lexicons/com/atproto/sync/listHosts.json @@ -0,0 +1,65 @@ +{ + "lexicon": 1, + "id": "com.atproto.sync.listHosts", + "defs": { + "main": { + "type": "query", + "description": "Enumerates upstream hosts (eg, PDS or relay instances) that this service consumes from. Implemented by relays.", + "parameters": { + "type": "params", + "properties": { + "limit": { + "type": "integer", + "minimum": 1, + "maximum": 1000, + "default": 200 + }, + "cursor": { + "type": "string" + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["hosts"], + "properties": { + "cursor": { + "type": "string" + }, + "hosts": { + "type": "array", + "items": { + "type": "ref", + "ref": "#host" + }, + "description": "Sort order is not formally specified. Recommended order is by time host was first seen by the server, with oldest first." + } + } + } + } + }, + "host": { + "type": "object", + "required": ["hostname"], + "properties": { + "hostname": { + "type": "string", + "description": "hostname of server; not a URL (no scheme)" + }, + "seq": { + "type": "integer", + "description": "Recent repo stream event sequence number. May be delayed from actual stream processing (eg, persisted cursor not in-memory cursor)." + }, + "accountCount": { + "type": "integer" + }, + "status": { + "type": "ref", + "ref": "com.atproto.sync.defs#hostStatus" + } + } + } + } +} diff --git a/lexicons/com/atproto/sync/listRepos.json b/lexicons/com/atproto/sync/listRepos.json new file mode 100644 index 0000000000..bd2c9aab4f --- /dev/null +++ b/lexicons/com/atproto/sync/listRepos.json @@ -0,0 +1,77 @@ +{ + "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": "#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", + "format": "tid" + }, + "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", + "deleted", + "deactivated", + "desynchronized", + "throttled" + ] + } + } + } + } +} diff --git a/lexicons/com/atproto/sync/listReposByCollection.json b/lexicons/com/atproto/sync/listReposByCollection.json new file mode 100644 index 0000000000..e968b71c83 --- /dev/null +++ b/lexicons/com/atproto/sync/listReposByCollection.json @@ -0,0 +1,59 @@ +{ + "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": "#repo" + } + } + } + } + } + }, + "repo": { + "type": "object", + "required": ["did"], + "properties": { + "did": { + "type": "string", + "format": "did" + } + } + } + } +} diff --git a/lexicons/com/atproto/sync/notifyOfUpdate.json b/lexicons/com/atproto/sync/notifyOfUpdate.json new file mode 100644 index 0000000000..630973862f --- /dev/null +++ b/lexicons/com/atproto/sync/notifyOfUpdate.json @@ -0,0 +1,23 @@ +{ + "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. DEPRECATED: just use com.atproto.sync.requestCrawl", + "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." + } + } + } + } + } + } +} diff --git a/lexicons/com/atproto/sync/requestCrawl.json b/lexicons/com/atproto/sync/requestCrawl.json new file mode 100644 index 0000000000..464c0e5f6e --- /dev/null +++ b/lexicons/com/atproto/sync/requestCrawl.json @@ -0,0 +1,28 @@ +{ + "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." + } + } + } + }, + "errors": [ + { + "name": "HostBanned" + } + ] + } + } +} diff --git a/lexicons/com/atproto/sync/subscribeRepos.json b/lexicons/com/atproto/sync/subscribeRepos.json new file mode 100644 index 0000000000..4c7cc991ac --- /dev/null +++ b/lexicons/com/atproto/sync/subscribeRepos.json @@ -0,0 +1,238 @@ +{ + "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": ["#commit", "#sync", "#identity", "#account", "#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": ["since"], + "properties": { + "seq": { + "type": "integer", + "description": "The stream sequence number of this message." + }, + "rebase": { + "type": "boolean", + "description": "DEPRECATED -- unused" + }, + "tooBig": { + "type": "boolean", + "description": "DEPRECATED -- replaced by #sync event and data limits. 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. Note that all other message types name this field 'did'." + }, + "commit": { + "type": "cid-link", + "description": "Repo commit object CID." + }, + "rev": { + "type": "string", + "format": "tid", + "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", + "format": "tid", + "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. The commit must be included as a block, and the commit block CID must be the first entry in the CAR header 'roots' list.", + "maxLength": 2000000 + }, + "ops": { + "type": "array", + "items": { + "type": "ref", + "ref": "#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": "DEPRECATED -- will soon always be empty. List of new blobs (by CID) referenced by records in this commit." + } + }, + "prevData": { + "type": "cid-link", + "description": "The root CID of the MST tree for the previous commit from this repo (indicated by the 'since' revision field in this message). Corresponds to the 'data' field in the repo commit object. NOTE: this field is effectively required for the 'inductive' version of firehose." + }, + "time": { + "type": "string", + "format": "datetime", + "description": "Timestamp of when this message was originally broadcast." + } + } + }, + "sync": { + "type": "object", + "description": "Updates the repo to a new state, without necessarily including that state on the firehose. Used to recover from broken commit streams, data loss incidents, or in situations where upstream host does not know recent state of the repository.", + "required": ["seq", "did", "blocks", "rev", "time"], + "properties": { + "seq": { + "type": "integer", + "description": "The stream sequence number of this message." + }, + "did": { + "type": "string", + "format": "did", + "description": "The account this repo event corresponds to. Must match that in the commit object." + }, + "blocks": { + "type": "bytes", + "description": "CAR file containing the commit, as a block. The CAR header must include the commit block CID as the first 'root'.", + "maxLength": 10000 + }, + "rev": { + "type": "string", + "description": "The rev of the commit. This value must match that in the commit object." + }, + "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", + "desynchronized", + "throttled" + ] + } + } + }, + "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." + }, + "prev": { + "type": "cid-link", + "description": "For updates and deletes, the previous record CID (required for inductive firehose). For creations, field should not be defined." + } + } + } + } +} diff --git a/lexicons/com/germnetwork/declaration.json b/lexicons/com/germnetwork/declaration.json new file mode 100644 index 0000000000..bce08581a3 --- /dev/null +++ b/lexicons/com/germnetwork/declaration.json @@ -0,0 +1,64 @@ +{ + "lexicon": 1, + "id": "com.germnetwork.declaration", + "defs": { + "main": { + "type": "record", + "description": "A declaration of a Germ Network account", + "key": "literal:self", + "record": { + "type": "object", + "required": ["version", "currentKey"], + "properties": { + "version": { + "type": "string", + "description": "Semver version number, without pre-release or build information, for the format of opaque content", + "minLength": 5, + "maxLength": 14 + }, + "currentKey": { + "type": "bytes", + "description": "Opaque value, an ed25519 public key prefixed with a byte enum" + }, + "messageMe": { + "type": "ref", + "description": "Controls who can message this account", + "ref": "#messageMe" + }, + "keyPackage": { + "type": "bytes", + "description": "Opaque value, contains MLS KeyPackage(s), and other signature data, and is signed by the currentKey" + }, + "continuityProofs": { + "type": "array", + "description": "Array of opaque values to allow for key rolling", + "items": { + "type": "bytes" + }, + "maxLength": 1000 + } + } + } + }, + "messageMe": { + "type": "object", + "required": ["showButtonTo", "messageMeUrl"], + "properties": { + "messageMeUrl": { + "type": "string", + "description": "A URL to present to an account that does not have its own com.germnetwork.declaration record, must have an empty fragment component, where the app should fill in the fragment component with the DIDs of the two accounts who wish to message each other", + "format": "uri", + "minLength": 1, + "maxLength": 2047 + }, + "showButtonTo": { + "type": "string", + "knownValues": ["none", "usersIFollow", "everyone"], + "description": "The policy of who can message the account, this value is included in the keyPackage, but is duplicated here to allow applications to decide if they should show a 'Message on Germ' button to the viewer.", + "minLength": 1, + "maxLength": 100 + } + } + } + } +} diff --git a/lexicons/tools/ozone/moderation/defs.json b/lexicons/tools/ozone/moderation/defs.json new file mode 100644 index 0000000000..9105a7c309 --- /dev/null +++ b/lexicons/tools/ozone/moderation/defs.json @@ -0,0 +1,1478 @@ +{ + "lexicon": 1, + "id": "tools.ozone.moderation.defs", + "defs": { + "modEventView": { + "type": "object", + "required": [ + "id", + "event", + "subject", + "subjectBlobCids", + "createdBy", + "createdAt" + ], + "properties": { + "id": { + "type": "integer" + }, + "event": { + "type": "union", + "refs": [ + "#modEventTakedown", + "#modEventReverseTakedown", + "#modEventComment", + "#modEventReport", + "#modEventLabel", + "#modEventAcknowledge", + "#modEventEscalate", + "#modEventMute", + "#modEventUnmute", + "#modEventMuteReporter", + "#modEventUnmuteReporter", + "#modEventEmail", + "#modEventResolveAppeal", + "#modEventDivert", + "#modEventTag", + "#accountEvent", + "#identityEvent", + "#recordEvent", + "#modEventPriorityScore", + "#ageAssuranceEvent", + "#ageAssuranceOverrideEvent", + "#ageAssurancePurgeEvent", + "#revokeAccountCredentialsEvent", + "#scheduleTakedownEvent", + "#cancelScheduledTakedownEvent" + ] + }, + "subject": { + "type": "union", + "refs": [ + "com.atproto.admin.defs#repoRef", + "com.atproto.repo.strongRef", + "chat.bsky.convo.defs#messageRef", + "chat.bsky.convo.defs#convoRef" + ] + }, + "subjectBlobCids": { + "type": "array", + "items": { + "type": "string" + } + }, + "createdBy": { + "type": "string", + "format": "did" + }, + "createdAt": { + "type": "string", + "format": "datetime" + }, + "creatorHandle": { + "type": "string" + }, + "subjectHandle": { + "type": "string" + }, + "modTool": { + "type": "ref", + "ref": "#modTool" + } + } + }, + "modEventViewDetail": { + "type": "object", + "required": [ + "id", + "event", + "subject", + "subjectBlobs", + "createdBy", + "createdAt" + ], + "properties": { + "id": { + "type": "integer" + }, + "event": { + "type": "union", + "refs": [ + "#modEventTakedown", + "#modEventReverseTakedown", + "#modEventComment", + "#modEventReport", + "#modEventLabel", + "#modEventAcknowledge", + "#modEventEscalate", + "#modEventMute", + "#modEventUnmute", + "#modEventMuteReporter", + "#modEventUnmuteReporter", + "#modEventEmail", + "#modEventResolveAppeal", + "#modEventDivert", + "#modEventTag", + "#accountEvent", + "#identityEvent", + "#recordEvent", + "#modEventPriorityScore", + "#ageAssuranceEvent", + "#ageAssuranceOverrideEvent", + "#ageAssurancePurgeEvent", + "#revokeAccountCredentialsEvent", + "#scheduleTakedownEvent", + "#cancelScheduledTakedownEvent" + ] + }, + "subject": { + "type": "union", + "refs": [ + "#repoView", + "#repoViewNotFound", + "#recordView", + "#recordViewNotFound", + "#convoView" + ] + }, + "subjectBlobs": { + "type": "array", + "items": { + "type": "ref", + "ref": "#blobView" + } + }, + "createdBy": { + "type": "string", + "format": "did" + }, + "createdAt": { + "type": "string", + "format": "datetime" + }, + "modTool": { + "type": "ref", + "ref": "#modTool" + } + } + }, + "subjectStatusView": { + "type": "object", + "required": ["id", "subject", "createdAt", "updatedAt", "reviewState"], + "properties": { + "id": { + "type": "integer" + }, + "subject": { + "type": "union", + "refs": [ + "com.atproto.admin.defs#repoRef", + "com.atproto.repo.strongRef", + "chat.bsky.convo.defs#messageRef", + "chat.bsky.convo.defs#convoRef" + ] + }, + "hosting": { + "type": "union", + "refs": ["#accountHosting", "#recordHosting"] + }, + "subjectBlobCids": { + "type": "array", + "items": { + "type": "string", + "format": "cid" + } + }, + "subjectRepoHandle": { + "type": "string" + }, + "updatedAt": { + "type": "string", + "format": "datetime", + "description": "Timestamp referencing when the last update was made to the moderation status of the subject" + }, + "createdAt": { + "type": "string", + "format": "datetime", + "description": "Timestamp referencing the first moderation status impacting event was emitted on the subject" + }, + "reviewState": { + "type": "ref", + "ref": "#subjectReviewState" + }, + "comment": { + "type": "string", + "description": "Sticky comment on the subject." + }, + "priorityScore": { + "type": "integer", + "description": "Numeric value representing the level of priority. Higher score means higher priority.", + "minimum": 0, + "maximum": 100 + }, + "muteUntil": { + "type": "string", + "format": "datetime" + }, + "muteReportingUntil": { + "type": "string", + "format": "datetime" + }, + "lastReviewedBy": { + "type": "string", + "format": "did" + }, + "lastReviewedAt": { + "type": "string", + "format": "datetime" + }, + "lastReportedAt": { + "type": "string", + "format": "datetime" + }, + "lastAppealedAt": { + "type": "string", + "format": "datetime", + "description": "Timestamp referencing when the author of the subject appealed a moderation action" + }, + "takendown": { + "type": "boolean" + }, + "appealed": { + "type": "boolean", + "description": "True indicates that the a previously taken moderator action was appealed against, by the author of the content. False indicates last appeal was resolved by moderators." + }, + "suspendUntil": { + "type": "string", + "format": "datetime" + }, + "tags": { + "type": "array", + "items": { + "type": "string" + } + }, + "accountStats": { + "description": "Statistics related to the account subject", + "type": "ref", + "ref": "#accountStats" + }, + "recordsStats": { + "description": "Statistics related to the record subjects authored by the subject's account", + "type": "ref", + "ref": "#recordsStats" + }, + "accountStrike": { + "description": "Strike information for the account (account-level only)", + "type": "ref", + "ref": "#accountStrike" + }, + "ageAssuranceState": { + "type": "string", + "description": "Current age assurance state of the subject.", + "knownValues": ["pending", "assured", "unknown", "reset", "blocked"] + }, + "ageAssuranceUpdatedBy": { + "type": "string", + "description": "Whether or not the last successful update to age assurance was made by the user or admin.", + "knownValues": ["admin", "user"] + } + } + }, + "subjectView": { + "description": "Detailed view of a subject. For record subjects, the author's repo and profile will be returned.", + "type": "object", + "required": ["type", "subject"], + "properties": { + "type": { + "type": "ref", + "ref": "com.atproto.moderation.defs#subjectType" + }, + "subject": { + "type": "string" + }, + "status": { + "type": "ref", + "ref": "#subjectStatusView" + }, + "repo": { + "type": "ref", + "ref": "#repoViewDetail" + }, + "profile": { + "type": "union", + "refs": [] + }, + "record": { + "type": "ref", + "ref": "#recordViewDetail" + } + } + }, + "accountStats": { + "description": "Statistics about a particular account subject", + "type": "object", + "properties": { + "reportCount": { + "description": "Total number of reports on the account", + "type": "integer" + }, + "appealCount": { + "description": "Total number of appeals against a moderation action on the account", + "type": "integer" + }, + "suspendCount": { + "description": "Number of times the account was suspended", + "type": "integer" + }, + "escalateCount": { + "description": "Number of times the account was escalated", + "type": "integer" + }, + "takedownCount": { + "description": "Number of times the account was taken down", + "type": "integer" + } + } + }, + "recordsStats": { + "description": "Statistics about a set of record subject items", + "type": "object", + "properties": { + "totalReports": { + "description": "Cumulative sum of the number of reports on the items in the set", + "type": "integer" + }, + "reportedCount": { + "description": "Number of items that were reported at least once", + "type": "integer" + }, + "escalatedCount": { + "description": "Number of items that were escalated at least once", + "type": "integer" + }, + "appealedCount": { + "description": "Number of items that were appealed at least once", + "type": "integer" + }, + "subjectCount": { + "description": "Total number of item in the set", + "type": "integer" + }, + "pendingCount": { + "description": "Number of item currently in \"reviewOpen\" or \"reviewEscalated\" state", + "type": "integer" + }, + "processedCount": { + "description": "Number of item currently in \"reviewNone\" or \"reviewClosed\" state", + "type": "integer" + }, + "takendownCount": { + "description": "Number of item currently taken down", + "type": "integer" + } + } + }, + "accountStrike": { + "description": "Strike information for an account", + "type": "object", + "properties": { + "activeStrikeCount": { + "description": "Current number of active strikes (excluding expired strikes)", + "type": "integer" + }, + "totalStrikeCount": { + "description": "Total number of strikes ever received (including expired strikes)", + "type": "integer" + }, + "firstStrikeAt": { + "description": "Timestamp of the first strike received", + "type": "string", + "format": "datetime" + }, + "lastStrikeAt": { + "description": "Timestamp of the most recent strike received", + "type": "string", + "format": "datetime" + } + } + }, + "subjectReviewState": { + "type": "string", + "knownValues": [ + "tools.ozone.moderation.defs#reviewOpen", + "tools.ozone.moderation.defs#reviewEscalated", + "tools.ozone.moderation.defs#reviewClosed", + "tools.ozone.moderation.defs#reviewNone" + ] + }, + "reviewOpen": { + "type": "token", + "description": "Moderator review status of a subject: Open. Indicates that the subject needs to be reviewed by a moderator" + }, + "reviewEscalated": { + "type": "token", + "description": "Moderator review status of a subject: Escalated. Indicates that the subject was escalated for review by a moderator" + }, + "reviewClosed": { + "type": "token", + "description": "Moderator review status of a subject: Closed. Indicates that the subject was already reviewed and resolved by a moderator" + }, + "reviewNone": { + "type": "token", + "description": "Moderator review status of a subject: Unnecessary. Indicates that the subject does not need a review at the moment but there is probably some moderation related metadata available for it" + }, + "modEventTakedown": { + "type": "object", + "description": "Take down a subject permanently or temporarily", + "properties": { + "comment": { + "type": "string" + }, + "durationInHours": { + "type": "integer", + "description": "Indicates how long the takedown should be in effect before automatically expiring." + }, + "acknowledgeAccountSubjects": { + "type": "boolean", + "description": "If true, all other reports on content authored by this account will be resolved (acknowledged)." + }, + "policies": { + "type": "array", + "maxLength": 5, + "items": { + "type": "string" + }, + "description": "Names/Keywords of the policies that drove the decision." + }, + "severityLevel": { + "type": "string", + "description": "Severity level of the violation (e.g., 'sev-0', 'sev-1', 'sev-2', etc.)." + }, + "targetServices": { + "type": "array", + "items": { + "type": "string", + "knownValues": ["appview", "pds"] + }, + "description": "List of services where the takedown should be applied. If empty or not provided, takedown is applied on all configured services." + }, + "strikeCount": { + "type": "integer", + "description": "Number of strikes to assign to the user for this violation." + }, + "strikeExpiresAt": { + "type": "string", + "format": "datetime", + "description": "When the strike should expire. If not provided, the strike never expires." + } + } + }, + "modEventReverseTakedown": { + "type": "object", + "description": "Revert take down action on a subject", + "properties": { + "comment": { + "type": "string", + "description": "Describe reasoning behind the reversal." + }, + "policies": { + "type": "array", + "maxLength": 5, + "items": { + "type": "string" + }, + "description": "Names/Keywords of the policy infraction for which takedown is being reversed." + }, + "severityLevel": { + "type": "string", + "description": "Severity level of the violation. Usually set from the last policy infraction's severity." + }, + "strikeCount": { + "type": "integer", + "description": "Number of strikes to subtract from the user's strike count. Usually set from the last policy infraction's severity." + } + } + }, + "modEventResolveAppeal": { + "type": "object", + "description": "Resolve appeal on a subject", + "properties": { + "comment": { + "type": "string", + "description": "Describe resolution." + } + } + }, + "modEventComment": { + "type": "object", + "description": "Add a comment to a subject. An empty comment will clear any previously set sticky comment.", + "properties": { + "comment": { + "type": "string" + }, + "sticky": { + "type": "boolean", + "description": "Make the comment persistent on the subject" + } + } + }, + "modEventReport": { + "type": "object", + "description": "Report a subject", + "required": ["reportType"], + "properties": { + "comment": { + "type": "string" + }, + "isReporterMuted": { + "type": "boolean", + "description": "Set to true if the reporter was muted from reporting at the time of the event. These reports won't impact the reviewState of the subject." + }, + "reportType": { + "type": "ref", + "ref": "com.atproto.moderation.defs#reasonType" + } + } + }, + "modEventLabel": { + "type": "object", + "description": "Apply/Negate labels on a subject", + "required": ["createLabelVals", "negateLabelVals"], + "properties": { + "comment": { + "type": "string" + }, + "createLabelVals": { + "type": "array", + "items": { + "type": "string" + } + }, + "negateLabelVals": { + "type": "array", + "items": { + "type": "string" + } + }, + "durationInHours": { + "type": "integer", + "description": "Indicates how long the label will remain on the subject. Only applies on labels that are being added." + } + } + }, + "modEventPriorityScore": { + "type": "object", + "description": "Set priority score of the subject. Higher score means higher priority.", + "required": ["score"], + "properties": { + "comment": { + "type": "string" + }, + "score": { + "type": "integer", + "minimum": 0, + "maximum": 100 + } + } + }, + "ageAssuranceEvent": { + "type": "object", + "description": "Age assurance info coming directly from users. Only works on DID subjects.", + "required": ["createdAt", "status", "attemptId"], + "properties": { + "createdAt": { + "type": "string", + "format": "datetime", + "description": "The date and time of this write operation." + }, + "attemptId": { + "type": "string", + "description": "The unique identifier for this instance of the age assurance flow, in UUID format." + }, + "status": { + "type": "string", + "description": "The status of the Age Assurance process.", + "knownValues": ["unknown", "pending", "assured"] + }, + "access": { + "type": "ref", + "ref": "app.bsky.ageassurance.defs#access" + }, + "countryCode": { + "type": "string", + "description": "The ISO 3166-1 alpha-2 country code provided when beginning the Age Assurance flow." + }, + "regionCode": { + "type": "string", + "description": "The ISO 3166-2 region code provided when beginning the Age Assurance flow." + }, + "initIp": { + "type": "string", + "description": "The IP address used when initiating the AA flow." + }, + "initUa": { + "type": "string", + "description": "The user agent used when initiating the AA flow." + }, + "completeIp": { + "type": "string", + "description": "The IP address used when completing the AA flow." + }, + "completeUa": { + "type": "string", + "description": "The user agent used when completing the AA flow." + } + } + }, + "ageAssuranceOverrideEvent": { + "type": "object", + "description": "Age assurance status override by moderators. Only works on DID subjects.", + "required": ["comment", "status"], + "properties": { + "status": { + "type": "string", + "description": "The status to be set for the user decided by a moderator, overriding whatever value the user had previously. Use reset to default to original state.", + "knownValues": ["assured", "reset", "blocked"] + }, + "access": { + "type": "ref", + "ref": "app.bsky.ageassurance.defs#access" + }, + "comment": { + "type": "string", + "minLength": 1, + "description": "Comment describing the reason for the override." + } + } + }, + "ageAssurancePurgeEvent": { + "type": "object", + "description": "Purges all age assurance events for the subject. Only works on DID subjects. Moderator-only.", + "required": ["comment"], + "properties": { + "comment": { + "type": "string", + "minLength": 1, + "description": "Comment describing the reason for the purge." + } + } + }, + "revokeAccountCredentialsEvent": { + "type": "object", + "description": "Account credentials revocation by moderators. Only works on DID subjects.", + "required": ["comment"], + "properties": { + "comment": { + "minLength": 1, + "type": "string", + "description": "Comment describing the reason for the revocation." + } + } + }, + "modEventAcknowledge": { + "type": "object", + "properties": { + "comment": { + "type": "string" + }, + "acknowledgeAccountSubjects": { + "type": "boolean", + "description": "If true, all other reports on content authored by this account will be resolved (acknowledged)." + } + } + }, + "modEventEscalate": { + "type": "object", + "properties": { + "comment": { + "type": "string" + } + } + }, + "modEventMute": { + "type": "object", + "description": "Mute incoming reports on a subject", + "required": ["durationInHours"], + "properties": { + "comment": { + "type": "string" + }, + "durationInHours": { + "type": "integer", + "description": "Indicates how long the subject should remain muted." + } + } + }, + "modEventUnmute": { + "type": "object", + "description": "Unmute action on a subject", + "properties": { + "comment": { + "type": "string", + "description": "Describe reasoning behind the reversal." + } + } + }, + "modEventMuteReporter": { + "type": "object", + "description": "Mute incoming reports from an account", + "properties": { + "comment": { + "type": "string" + }, + "durationInHours": { + "type": "integer", + "description": "Indicates how long the account should remain muted. Falsy value here means a permanent mute." + } + } + }, + "modEventUnmuteReporter": { + "type": "object", + "description": "Unmute incoming reports from an account", + "properties": { + "comment": { + "type": "string", + "description": "Describe reasoning behind the reversal." + } + } + }, + "modEventEmail": { + "type": "object", + "description": "Keep a log of outgoing email to a user", + "required": ["subjectLine"], + "properties": { + "subjectLine": { + "type": "string", + "description": "The subject line of the email sent to the user." + }, + "content": { + "type": "string", + "description": "The content of the email sent to the user." + }, + "comment": { + "type": "string", + "description": "Additional comment about the outgoing comm." + }, + "policies": { + "type": "array", + "maxLength": 5, + "items": { + "type": "string" + }, + "description": "Names/Keywords of the policies that necessitated the email." + }, + "severityLevel": { + "type": "string", + "description": "Severity level of the violation. Normally 'sev-1' that adds strike on repeat offense" + }, + "strikeCount": { + "type": "integer", + "description": "Number of strikes to assign to the user for this violation. Normally 0 as an indicator of a warning and only added as a strike on a repeat offense." + }, + "strikeExpiresAt": { + "type": "string", + "format": "datetime", + "description": "When the strike should expire. If not provided, the strike never expires." + }, + "isDelivered": { + "type": "boolean", + "description": "Indicates whether the email was successfully delivered to the user's inbox." + } + } + }, + "modEventDivert": { + "type": "object", + "description": "Divert a record's blobs to a 3rd party service for further scanning/tagging", + "properties": { + "comment": { + "type": "string" + } + } + }, + "modEventTag": { + "type": "object", + "description": "Add/Remove a tag on a subject", + "required": ["add", "remove"], + "properties": { + "add": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Tags to be added to the subject. If already exists, won't be duplicated." + }, + "remove": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Tags to be removed to the subject. Ignores a tag If it doesn't exist, won't be duplicated." + }, + "comment": { + "type": "string", + "description": "Additional comment about added/removed tags." + }, + "durationInHours": { + "type": "integer", + "description": "Indicates how long the tags being added should remain before automatically being removed. Only applies to tags being added." + } + } + }, + "accountEvent": { + "type": "object", + "description": "Logs account status related events on a repo subject. Normally captured by automod from the firehose and emitted to ozone for historical tracking.", + "required": ["timestamp", "active"], + "properties": { + "comment": { + "type": "string" + }, + "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", + "knownValues": [ + "unknown", + "deactivated", + "deleted", + "takendown", + "suspended", + "tombstoned" + ] + }, + "timestamp": { + "type": "string", + "format": "datetime" + } + } + }, + "identityEvent": { + "type": "object", + "description": "Logs identity related events on a repo subject. Normally captured by automod from the firehose and emitted to ozone for historical tracking.", + "required": ["timestamp"], + "properties": { + "comment": { + "type": "string" + }, + "handle": { + "type": "string", + "format": "handle" + }, + "pdsHost": { + "type": "string", + "format": "uri" + }, + "tombstone": { + "type": "boolean" + }, + "timestamp": { + "type": "string", + "format": "datetime" + } + } + }, + "recordEvent": { + "type": "object", + "description": "Logs lifecycle event on a record subject. Normally captured by automod from the firehose and emitted to ozone for historical tracking.", + "required": ["timestamp", "op"], + "properties": { + "comment": { + "type": "string" + }, + "op": { + "type": "string", + "knownValues": ["create", "update", "delete"] + }, + "cid": { + "type": "string", + "format": "cid" + }, + "timestamp": { + "type": "string", + "format": "datetime" + } + } + }, + "scheduleTakedownEvent": { + "type": "object", + "description": "Logs a scheduled takedown action for an account.", + "properties": { + "comment": { + "type": "string" + }, + "executeAt": { + "type": "string", + "format": "datetime" + }, + "executeAfter": { + "type": "string", + "format": "datetime" + }, + "executeUntil": { + "type": "string", + "format": "datetime" + } + } + }, + "cancelScheduledTakedownEvent": { + "type": "object", + "description": "Logs cancellation of a scheduled takedown action for an account.", + "properties": { + "comment": { + "type": "string" + } + } + }, + "repoView": { + "type": "object", + "required": [ + "did", + "handle", + "relatedRecords", + "indexedAt", + "moderation" + ], + "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" + }, + "moderation": { + "type": "ref", + "ref": "#moderation" + }, + "invitedBy": { + "type": "ref", + "ref": "com.atproto.server.defs#inviteCode" + }, + "invitesDisabled": { + "type": "boolean" + }, + "inviteNote": { + "type": "string" + }, + "deactivatedAt": { + "type": "string", + "format": "datetime" + }, + "threatSignatures": { + "type": "array", + "items": { + "type": "ref", + "ref": "com.atproto.admin.defs#threatSignature" + } + } + } + }, + "repoViewDetail": { + "type": "object", + "required": [ + "did", + "handle", + "relatedRecords", + "indexedAt", + "moderation" + ], + "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" + }, + "moderation": { + "type": "ref", + "ref": "#moderationDetail" + }, + "labels": { + "type": "array", + "items": { + "type": "ref", + "ref": "com.atproto.label.defs#label" + } + }, + "invitedBy": { + "type": "ref", + "ref": "com.atproto.server.defs#inviteCode" + }, + "invites": { + "type": "array", + "items": { + "type": "ref", + "ref": "com.atproto.server.defs#inviteCode" + } + }, + "invitesDisabled": { + "type": "boolean" + }, + "inviteNote": { + "type": "string" + }, + "emailConfirmedAt": { + "type": "string", + "format": "datetime" + }, + "deactivatedAt": { + "type": "string", + "format": "datetime" + }, + "threatSignatures": { + "type": "array", + "items": { + "type": "ref", + "ref": "com.atproto.admin.defs#threatSignature" + } + } + } + }, + "repoViewNotFound": { + "type": "object", + "required": ["did"], + "properties": { + "did": { + "type": "string", + "format": "did" + } + } + }, + "recordView": { + "type": "object", + "required": [ + "uri", + "cid", + "value", + "blobCids", + "indexedAt", + "moderation", + "repo" + ], + "properties": { + "uri": { + "type": "string", + "format": "at-uri" + }, + "cid": { + "type": "string", + "format": "cid" + }, + "value": { + "type": "unknown" + }, + "blobCids": { + "type": "array", + "items": { + "type": "string", + "format": "cid" + } + }, + "indexedAt": { + "type": "string", + "format": "datetime" + }, + "moderation": { + "type": "ref", + "ref": "#moderation" + }, + "repo": { + "type": "ref", + "ref": "#repoView" + } + } + }, + "recordViewDetail": { + "type": "object", + "required": [ + "uri", + "cid", + "value", + "blobs", + "indexedAt", + "moderation", + "repo" + ], + "properties": { + "uri": { + "type": "string", + "format": "at-uri" + }, + "cid": { + "type": "string", + "format": "cid" + }, + "value": { + "type": "unknown" + }, + "blobs": { + "type": "array", + "items": { + "type": "ref", + "ref": "#blobView" + } + }, + "labels": { + "type": "array", + "items": { + "type": "ref", + "ref": "com.atproto.label.defs#label" + } + }, + "indexedAt": { + "type": "string", + "format": "datetime" + }, + "moderation": { + "type": "ref", + "ref": "#moderationDetail" + }, + "repo": { + "type": "ref", + "ref": "#repoView" + } + } + }, + "recordViewNotFound": { + "type": "object", + "required": ["uri"], + "properties": { + "uri": { + "type": "string", + "format": "at-uri" + } + } + }, + "convoView": { + "type": "object", + "required": ["did", "convoId"], + "properties": { + "did": { + "type": "string", + "format": "did" + }, + "convoId": { + "type": "string" + } + } + }, + "moderation": { + "type": "object", + "properties": { + "subjectStatus": { + "type": "ref", + "ref": "#subjectStatusView" + } + } + }, + "moderationDetail": { + "type": "object", + "properties": { + "subjectStatus": { + "type": "ref", + "ref": "#subjectStatusView" + } + } + }, + "blobView": { + "type": "object", + "required": ["cid", "mimeType", "size", "createdAt"], + "properties": { + "cid": { + "type": "string", + "format": "cid" + }, + "mimeType": { + "type": "string" + }, + "size": { + "type": "integer" + }, + "createdAt": { + "type": "string", + "format": "datetime" + }, + "details": { + "type": "union", + "refs": ["#imageDetails", "#videoDetails"] + }, + "moderation": { + "type": "ref", + "ref": "#moderation" + } + } + }, + "imageDetails": { + "type": "object", + "required": ["width", "height"], + "properties": { + "width": { + "type": "integer" + }, + "height": { + "type": "integer" + } + } + }, + "videoDetails": { + "type": "object", + "required": ["width", "height", "length"], + "properties": { + "width": { + "type": "integer" + }, + "height": { + "type": "integer" + }, + "length": { + "type": "integer" + } + } + }, + "accountHosting": { + "type": "object", + "required": ["status"], + "properties": { + "status": { + "type": "string", + "knownValues": [ + "takendown", + "suspended", + "deleted", + "deactivated", + "unknown" + ] + }, + "updatedAt": { + "type": "string", + "format": "datetime" + }, + "createdAt": { + "type": "string", + "format": "datetime" + }, + "deletedAt": { + "type": "string", + "format": "datetime" + }, + "deactivatedAt": { + "type": "string", + "format": "datetime" + }, + "reactivatedAt": { + "type": "string", + "format": "datetime" + } + } + }, + "recordHosting": { + "type": "object", + "required": ["status"], + "properties": { + "status": { + "type": "string", + "knownValues": ["deleted", "unknown"] + }, + "updatedAt": { + "type": "string", + "format": "datetime" + }, + "createdAt": { + "type": "string", + "format": "datetime" + }, + "deletedAt": { + "type": "string", + "format": "datetime" + } + } + }, + "reporterStats": { + "type": "object", + "required": [ + "did", + "accountReportCount", + "recordReportCount", + "reportedAccountCount", + "reportedRecordCount", + "takendownAccountCount", + "takendownRecordCount", + "labeledAccountCount", + "labeledRecordCount" + ], + "properties": { + "did": { + "type": "string", + "format": "did" + }, + "accountReportCount": { + "type": "integer", + "description": "The total number of reports made by the user on accounts." + }, + "recordReportCount": { + "type": "integer", + "description": "The total number of reports made by the user on records." + }, + "reportedAccountCount": { + "type": "integer", + "description": "The total number of accounts reported by the user." + }, + "reportedRecordCount": { + "type": "integer", + "description": "The total number of records reported by the user." + }, + "takendownAccountCount": { + "type": "integer", + "description": "The total number of accounts taken down as a result of the user's reports." + }, + "takendownRecordCount": { + "type": "integer", + "description": "The total number of records taken down as a result of the user's reports." + }, + "labeledAccountCount": { + "type": "integer", + "description": "The total number of accounts labeled as a result of the user's reports." + }, + "labeledRecordCount": { + "type": "integer", + "description": "The total number of records labeled as a result of the user's reports." + } + } + }, + "modTool": { + "type": "object", + "description": "Moderation tool information for tracing the source of the action", + "required": ["name"], + "properties": { + "name": { + "type": "string", + "description": "Name/identifier of the source (e.g., 'automod', 'ozone/workspace')" + }, + "meta": { + "type": "unknown", + "description": "Additional arbitrary metadata about the source" + } + } + }, + "timelineEventPlcCreate": { + "type": "token", + "description": "Moderation event timeline event for a PLC create operation" + }, + "timelineEventPlcOperation": { + "type": "token", + "description": "Moderation event timeline event for generic PLC operation" + }, + "timelineEventPlcTombstone": { + "type": "token", + "description": "Moderation event timeline event for a PLC tombstone operation" + }, + "scheduledActionView": { + "type": "object", + "description": "View of a scheduled moderation action", + "required": ["id", "action", "did", "createdBy", "createdAt", "status"], + "properties": { + "id": { + "type": "integer", + "description": "Auto-incrementing row ID" + }, + "action": { + "type": "string", + "knownValues": ["takedown"], + "description": "Type of action to be executed" + }, + "eventData": { + "type": "unknown", + "description": "Serialized event object that will be propagated to the event when performed" + }, + "did": { + "type": "string", + "format": "did", + "description": "Subject DID for the action" + }, + "executeAt": { + "type": "string", + "format": "datetime", + "description": "Exact time to execute the action" + }, + "executeAfter": { + "type": "string", + "format": "datetime", + "description": "Earliest time to execute the action (for randomized scheduling)" + }, + "executeUntil": { + "type": "string", + "format": "datetime", + "description": "Latest time to execute the action (for randomized scheduling)" + }, + "randomizeExecution": { + "type": "boolean", + "description": "Whether execution time should be randomized within the specified range" + }, + "createdBy": { + "type": "string", + "format": "did", + "description": "DID of the user who created this scheduled action" + }, + "createdAt": { + "type": "string", + "format": "datetime", + "description": "When the scheduled action was created" + }, + "updatedAt": { + "type": "string", + "format": "datetime", + "description": "When the scheduled action was last updated" + }, + "status": { + "type": "string", + "knownValues": ["pending", "executed", "cancelled", "failed"], + "description": "Current status of the scheduled action" + }, + "lastExecutedAt": { + "type": "string", + "format": "datetime", + "description": "When the action was last attempted to be executed" + }, + "lastFailureReason": { + "type": "string", + "description": "Reason for the last execution failure" + }, + "executionEventId": { + "type": "integer", + "description": "ID of the moderation event created when action was successfully executed" + } + } + } + } +} diff --git a/lexicons/tools/ozone/queue/defs.json b/lexicons/tools/ozone/queue/defs.json new file mode 100644 index 0000000000..81890d80ab --- /dev/null +++ b/lexicons/tools/ozone/queue/defs.json @@ -0,0 +1,148 @@ +{ + "lexicon": 1, + "id": "tools.ozone.queue.defs", + "defs": { + "queueView": { + "type": "object", + "required": [ + "id", + "name", + "subjectTypes", + "reportTypes", + "createdBy", + "createdAt", + "updatedAt", + "enabled", + "stats" + ], + "properties": { + "id": { + "type": "integer", + "description": "Queue ID" + }, + "name": { + "type": "string", + "description": "Display name of the queue" + }, + "subjectTypes": { + "type": "array", + "minLength": 1, + "items": { + "type": "string", + "knownValues": ["account", "record", "message"] + }, + "description": "Subject types this queue accepts." + }, + "collection": { + "type": "string", + "format": "nsid", + "description": "Collection name for record subjects (e.g., 'app.bsky.feed.post')" + }, + "reportTypes": { + "type": "array", + "items": { + "type": "string" + }, + "minLength": 1, + "description": "Report reason types this queue accepts (fully qualified NSIDs)" + }, + "description": { + "type": "string", + "description": "Optional description of the queue" + }, + "createdBy": { + "type": "string", + "format": "did", + "description": "DID of moderator who created this queue" + }, + "createdAt": { + "type": "string", + "format": "datetime" + }, + "updatedAt": { + "type": "string", + "format": "datetime" + }, + "enabled": { + "type": "boolean", + "description": "Whether this queue is currently active" + }, + "deletedAt": { + "type": "string", + "format": "datetime", + "description": "When the queue was deleted, if applicable" + }, + "stats": { + "type": "ref", + "ref": "#queueStats", + "description": "Statistics about this queue" + } + } + }, + "queueStats": { + "type": "object", + "required": [], + "properties": { + "pendingCount": { + "type": "integer", + "description": "Number of reports in 'open' status" + }, + "actionedCount": { + "type": "integer", + "description": "Number of reports in 'closed' status" + }, + "escalatedCount": { + "type": "integer", + "description": "Number of reports in 'escalated' status" + }, + "inboundCount": { + "type": "integer", + "description": "Reports received in this queue in the last 24 hours." + }, + "actionRate": { + "type": "integer", + "description": "Percentage of reports actioned (actionedCount / inboundCount * 100), rounded to nearest integer. Absent when inboundCount is 0." + }, + "avgHandlingTimeSec": { + "type": "integer", + "description": "Average time in seconds from report creation to close, for reports closed in this period." + }, + "lastUpdated": { + "type": "string", + "format": "datetime", + "description": "When these statistics were last computed" + } + } + }, + "assignmentView": { + "type": "object", + "required": ["id", "did", "queue", "startAt"], + "properties": { + "id": { + "type": "integer" + }, + "did": { + "type": "string", + "format": "did" + }, + "moderator": { + "type": "ref", + "ref": "tools.ozone.team.defs#member", + "description": "The moderator assigned to this queue" + }, + "queue": { + "type": "ref", + "ref": "#queueView" + }, + "startAt": { + "type": "string", + "format": "datetime" + }, + "endAt": { + "type": "string", + "format": "datetime" + } + } + } + } +} diff --git a/lexicons/tools/ozone/report/defs.json b/lexicons/tools/ozone/report/defs.json new file mode 100644 index 0000000000..dc07aa8b94 --- /dev/null +++ b/lexicons/tools/ozone/report/defs.json @@ -0,0 +1,580 @@ +{ + "lexicon": 1, + "id": "tools.ozone.report.defs", + "defs": { + "reasonType": { + "type": "string", + "knownValues": [ + "tools.ozone.report.defs#reasonAppeal", + "tools.ozone.report.defs#reasonOther", + "tools.ozone.report.defs#reasonViolenceAnimal", + "tools.ozone.report.defs#reasonViolenceThreats", + "tools.ozone.report.defs#reasonViolenceGraphicContent", + "tools.ozone.report.defs#reasonViolenceGlorification", + "tools.ozone.report.defs#reasonViolenceExtremistContent", + "tools.ozone.report.defs#reasonViolenceTrafficking", + "tools.ozone.report.defs#reasonViolenceOther", + "tools.ozone.report.defs#reasonSexualAbuseContent", + "tools.ozone.report.defs#reasonSexualNCII", + "tools.ozone.report.defs#reasonSexualDeepfake", + "tools.ozone.report.defs#reasonSexualAnimal", + "tools.ozone.report.defs#reasonSexualUnlabeled", + "tools.ozone.report.defs#reasonSexualOther", + "tools.ozone.report.defs#reasonChildSafetyCSAM", + "tools.ozone.report.defs#reasonChildSafetyGroom", + "tools.ozone.report.defs#reasonChildSafetyPrivacy", + "tools.ozone.report.defs#reasonChildSafetyHarassment", + "tools.ozone.report.defs#reasonChildSafetyOther", + "tools.ozone.report.defs#reasonHarassmentTroll", + "tools.ozone.report.defs#reasonHarassmentTargeted", + "tools.ozone.report.defs#reasonHarassmentHateSpeech", + "tools.ozone.report.defs#reasonHarassmentDoxxing", + "tools.ozone.report.defs#reasonHarassmentOther", + "tools.ozone.report.defs#reasonMisleadingBot", + "tools.ozone.report.defs#reasonMisleadingImpersonation", + "tools.ozone.report.defs#reasonMisleadingSpam", + "tools.ozone.report.defs#reasonMisleadingScam", + "tools.ozone.report.defs#reasonMisleadingElections", + "tools.ozone.report.defs#reasonMisleadingOther", + "tools.ozone.report.defs#reasonRuleSiteSecurity", + "tools.ozone.report.defs#reasonRuleProhibitedSales", + "tools.ozone.report.defs#reasonRuleBanEvasion", + "tools.ozone.report.defs#reasonRuleOther", + "tools.ozone.report.defs#reasonSelfHarmContent", + "tools.ozone.report.defs#reasonSelfHarmED", + "tools.ozone.report.defs#reasonSelfHarmStunts", + "tools.ozone.report.defs#reasonSelfHarmSubstances", + "tools.ozone.report.defs#reasonSelfHarmOther" + ] + }, + "reasonAppeal": { + "type": "token", + "description": "Appeal a previously taken moderation action" + }, + "reasonOther": { + "type": "token", + "description": "An issue not included in these options" + }, + "reasonViolenceAnimal": { + "type": "token", + "description": "Animal welfare violations" + }, + "reasonViolenceThreats": { + "type": "token", + "description": "Threats or incitement" + }, + "reasonViolenceGraphicContent": { + "type": "token", + "description": "Graphic violent content" + }, + "reasonViolenceGlorification": { + "type": "token", + "description": "Glorification of violence" + }, + "reasonViolenceExtremistContent": { + "type": "token", + "description": "Extremist content. These reports will be sent only be sent to the application's Moderation Authority." + }, + "reasonViolenceTrafficking": { + "type": "token", + "description": "Human trafficking" + }, + "reasonViolenceOther": { + "type": "token", + "description": "Other violent content" + }, + "reasonSexualAbuseContent": { + "type": "token", + "description": "Adult sexual abuse content" + }, + "reasonSexualNCII": { + "type": "token", + "description": "Non-consensual intimate imagery" + }, + "reasonSexualDeepfake": { + "type": "token", + "description": "Deepfake adult content" + }, + "reasonSexualAnimal": { + "type": "token", + "description": "Animal sexual abuse" + }, + "reasonSexualUnlabeled": { + "type": "token", + "description": "Unlabelled adult content" + }, + "reasonSexualOther": { + "type": "token", + "description": "Other sexual violence content" + }, + "reasonChildSafetyCSAM": { + "type": "token", + "description": "Child sexual abuse material (CSAM). These reports will be sent only be sent to the application's Moderation Authority." + }, + "reasonChildSafetyGroom": { + "type": "token", + "description": "Grooming or predatory behavior. These reports will be sent only be sent to the application's Moderation Authority." + }, + "reasonChildSafetyPrivacy": { + "type": "token", + "description": "Privacy violation involving a minor" + }, + "reasonChildSafetyHarassment": { + "type": "token", + "description": "Harassment or bullying of minors" + }, + "reasonChildSafetyOther": { + "type": "token", + "description": "Other child safety. These reports will be sent only be sent to the application's Moderation Authority." + }, + "reasonHarassmentTroll": { + "type": "token", + "description": "Trolling" + }, + "reasonHarassmentTargeted": { + "type": "token", + "description": "Targeted harassment" + }, + "reasonHarassmentHateSpeech": { + "type": "token", + "description": "Hate speech" + }, + "reasonHarassmentDoxxing": { + "type": "token", + "description": "Doxxing" + }, + "reasonHarassmentOther": { + "type": "token", + "description": "Other harassing or hateful content" + }, + "reasonMisleadingBot": { + "type": "token", + "description": "Fake account or bot" + }, + "reasonMisleadingImpersonation": { + "type": "token", + "description": "Impersonation" + }, + "reasonMisleadingSpam": { + "type": "token", + "description": "Spam" + }, + "reasonMisleadingScam": { + "type": "token", + "description": "Scam" + }, + "reasonMisleadingElections": { + "type": "token", + "description": "False information about elections" + }, + "reasonMisleadingOther": { + "type": "token", + "description": "Other misleading content" + }, + "reasonRuleSiteSecurity": { + "type": "token", + "description": "Hacking or system attacks" + }, + "reasonRuleProhibitedSales": { + "type": "token", + "description": "Promoting or selling prohibited items or services" + }, + "reasonRuleBanEvasion": { + "type": "token", + "description": "Banned user returning" + }, + "reasonRuleOther": { + "type": "token", + "description": "Other" + }, + "reasonSelfHarmContent": { + "type": "token", + "description": "Content promoting or depicting self-harm" + }, + "reasonSelfHarmED": { + "type": "token", + "description": "Eating disorders" + }, + "reasonSelfHarmStunts": { + "type": "token", + "description": "Dangerous challenges or activities" + }, + "reasonSelfHarmSubstances": { + "type": "token", + "description": "Dangerous substances or drug abuse" + }, + "reasonSelfHarmOther": { + "type": "token", + "description": "Other dangerous content" + }, + "reportAssignment": { + "type": "object", + "description": "Information about the moderator currently assigned to a report.", + "required": ["did", "assignedAt"], + "properties": { + "did": { + "type": "string", + "format": "did", + "description": "DID of the assigned moderator" + }, + "moderator": { + "type": "ref", + "ref": "tools.ozone.team.defs#member", + "description": "Full member record of the assigned moderator" + }, + "assignedAt": { + "type": "string", + "format": "datetime", + "description": "When the report was assigned" + } + } + }, + "reportView": { + "type": "object", + "required": [ + "id", + "eventId", + "status", + "subject", + "reportType", + "reportedBy", + "reporter", + "createdAt" + ], + "properties": { + "id": { + "type": "integer", + "description": "Report ID" + }, + "eventId": { + "type": "integer", + "description": "ID of the moderation event that created this report" + }, + "status": { + "type": "string", + "knownValues": ["open", "closed", "escalated", "queued", "assigned"], + "description": "Current status of the report" + }, + "subject": { + "type": "ref", + "ref": "tools.ozone.moderation.defs#subjectView", + "description": "The subject that was reported with full details" + }, + "reportType": { + "type": "ref", + "ref": "com.atproto.moderation.defs#reasonType", + "description": "Type of report" + }, + "reportedBy": { + "type": "string", + "format": "did", + "description": "DID of the user who made the report" + }, + "reporter": { + "type": "ref", + "ref": "tools.ozone.moderation.defs#subjectView", + "description": "Full subject view of the reporter account" + }, + "comment": { + "type": "string", + "description": "Comment provided by the reporter" + }, + "createdAt": { + "type": "string", + "format": "datetime", + "description": "When the report was created" + }, + "updatedAt": { + "type": "string", + "format": "datetime", + "description": "When the report was last updated" + }, + "queuedAt": { + "type": "string", + "format": "datetime", + "description": "When the report was assigned to its current queue" + }, + "actionEventIds": { + "type": "array", + "items": { + "type": "integer" + }, + "description": "Array of moderation event IDs representing actions taken on this report (sorted DESC, most recent first)" + }, + "actions": { + "type": "array", + "items": { + "type": "ref", + "ref": "tools.ozone.moderation.defs#modEventView" + }, + "description": "Optional: expanded action events" + }, + "actionNote": { + "type": "string", + "description": "Note sent to reporter when report was actioned" + }, + "subjectStatus": { + "type": "ref", + "ref": "tools.ozone.moderation.defs#subjectStatusView", + "description": "Current status of the reported subject" + }, + "relatedReportCount": { + "type": "integer", + "description": "Number of other pending reports on the same subject" + }, + "assignment": { + "type": "ref", + "ref": "#reportAssignment", + "description": "Information about moderator currently assigned to this report (if any)" + }, + "queue": { + "type": "ref", + "ref": "tools.ozone.queue.defs#queueView", + "description": "The queue this report is assigned to (if any)" + }, + "isMuted": { + "type": "boolean", + "description": "Whether this report is muted. A report is muted if the reporter was muted or the subject was muted at the time the report was created." + } + } + }, + "queueActivity": { + "type": "object", + "description": "Activity recording a report being routed to a queue.", + "properties": { + "previousStatus": { + "type": "string", + "knownValues": ["open", "closed", "escalated", "queued", "assigned"], + "description": "The report's status before this activity. Populated automatically from the report row; not required in input." + } + } + }, + "assignmentActivity": { + "type": "object", + "description": "Activity recording a moderator being assigned to a report.", + "properties": { + "previousStatus": { + "type": "string", + "knownValues": ["open", "closed", "escalated", "queued", "assigned"], + "description": "The report's status before this activity. Populated automatically from the report row; not required in input." + } + } + }, + "escalationActivity": { + "type": "object", + "description": "Activity recording a report being escalated.", + "properties": { + "previousStatus": { + "type": "string", + "knownValues": ["open", "closed", "escalated", "queued", "assigned"], + "description": "The report's status before this activity. Populated automatically from the report row; not required in input." + } + } + }, + "closeActivity": { + "type": "object", + "description": "Activity recording a report being closed.", + "properties": { + "previousStatus": { + "type": "string", + "knownValues": ["open", "closed", "escalated", "queued", "assigned"], + "description": "The report's status before this activity. Populated automatically from the report row; not required in input." + } + } + }, + "reopenActivity": { + "type": "object", + "description": "Activity recording a closed report being reopened. Only valid when the report is in 'closed' status.", + "properties": { + "previousStatus": { + "type": "string", + "knownValues": ["open", "closed", "escalated", "queued", "assigned"], + "description": "The report's status before this activity. Populated automatically from the report row; not required in input." + } + } + }, + "noteActivity": { + "type": "object", + "description": "Activity recording a note on a report. Use internalNote for moderator-only notes or publicNote for reporter-visible notes (or both).", + "properties": {} + }, + "reportActivityView": { + "type": "object", + "description": "A single activity entry on a report.", + "required": [ + "id", + "reportId", + "activity", + "isAutomated", + "createdBy", + "createdAt" + ], + "properties": { + "id": { + "type": "integer", + "description": "Activity ID" + }, + "reportId": { + "type": "integer", + "description": "ID of the report this activity belongs to" + }, + "activity": { + "type": "union", + "refs": [ + "#queueActivity", + "#assignmentActivity", + "#escalationActivity", + "#closeActivity", + "#reopenActivity", + "#noteActivity" + ], + "description": "The typed activity object describing what occurred." + }, + "internalNote": { + "type": "string", + "description": "Optional moderator-only note. Not visible to reporters." + }, + "publicNote": { + "type": "string", + "description": "Optional public note, potentially visible to the reporter." + }, + "meta": { + "type": "unknown", + "description": "Extensible JSON payload for loose activity-specific metadata (e.g. assignmentId)." + }, + "isAutomated": { + "type": "boolean", + "description": "True if this activity was created by an automated process (e.g. queue router) rather than a direct human action." + }, + "createdBy": { + "type": "string", + "format": "did", + "description": "DID of the actor who created this activity, or the service DID for automated activities." + }, + "moderator": { + "type": "ref", + "ref": "tools.ozone.team.defs#member", + "description": "Full member record of the moderator who created this activity" + }, + "report": { + "type": "ref", + "ref": "#reportView", + "description": "Full view of the report this activity belongs to." + }, + "createdAt": { + "type": "string", + "format": "datetime", + "description": "When this activity was created" + } + } + }, + "liveStats": { + "description": "Live statistics for reports for the current calendar day, filterable by queue, moderator, or report type.", + "type": "object", + "properties": { + "pendingCount": { + "type": "integer", + "description": "Number of reports currently not closed." + }, + "actionedCount": { + "type": "integer", + "description": "Number of reports closed today." + }, + "escalatedCount": { + "type": "integer", + "description": "Number of reports escalated today." + }, + "inboundCount": { + "type": "integer", + "description": "Reports received today." + }, + "actionRate": { + "type": "integer", + "description": "Percentage of reports actioned (actionedCount / inboundCount * 100), rounded to nearest integer." + }, + "avgHandlingTimeSec": { + "type": "integer", + "description": "Average time in seconds from report creation (or moderator assignment) to close." + }, + "lastUpdated": { + "type": "string", + "format": "datetime", + "description": "When these statistics were last computed." + } + } + }, + "historicalStats": { + "description": "A single daily snapshot of report statistics for a calendar date.", + "type": "object", + "required": ["date"], + "properties": { + "date": { + "type": "string", + "description": "The calendar date this snapshot covers (YYYY-MM-DD)." + }, + "computedAt": { + "type": "string", + "format": "datetime", + "description": "When this snapshot was last computed." + }, + "pendingCount": { + "type": "integer", + "description": "Number of reports not closed at time of computation." + }, + "actionedCount": { + "type": "integer", + "description": "Number of reports closed during this day." + }, + "escalatedCount": { + "type": "integer", + "description": "Number of reports escalated during this day." + }, + "inboundCount": { + "type": "integer", + "description": "Reports received during this day." + }, + "actionRate": { + "type": "integer", + "description": "Percentage of reports actioned (actionedCount / inboundCount * 100), rounded to nearest integer." + }, + "avgHandlingTimeSec": { + "type": "integer", + "description": "Average time in seconds from report creation (or moderator assignment) to close." + } + } + }, + "assignmentView": { + "type": "object", + "required": ["id", "did", "reportId", "startAt"], + "properties": { + "id": { + "type": "integer" + }, + "did": { + "type": "string", + "format": "did" + }, + "moderator": { + "type": "ref", + "ref": "tools.ozone.team.defs#member", + "description": "The moderator assigned to this report" + }, + "queue": { + "type": "ref", + "ref": "tools.ozone.queue.defs#queueView" + }, + "reportId": { + "type": "integer" + }, + "startAt": { + "type": "string", + "format": "datetime" + }, + "endAt": { + "type": "string", + "format": "datetime" + } + } + } + } +} diff --git a/lexicons/tools/ozone/team/defs.json b/lexicons/tools/ozone/team/defs.json new file mode 100644 index 0000000000..9aa6da4e89 --- /dev/null +++ b/lexicons/tools/ozone/team/defs.json @@ -0,0 +1,59 @@ +{ + "lexicon": 1, + "id": "tools.ozone.team.defs", + "defs": { + "member": { + "type": "object", + "required": ["did", "role"], + "properties": { + "did": { + "type": "string", + "format": "did" + }, + "disabled": { + "type": "boolean" + }, + "profile": { + "type": "ref", + "ref": "app.bsky.actor.defs#profileViewDetailed" + }, + "createdAt": { + "type": "string", + "format": "datetime" + }, + "updatedAt": { + "type": "string", + "format": "datetime" + }, + "lastUpdatedBy": { + "type": "string" + }, + "role": { + "type": "string", + "knownValues": [ + "tools.ozone.team.defs#roleAdmin", + "tools.ozone.team.defs#roleModerator", + "tools.ozone.team.defs#roleTriage", + "tools.ozone.team.defs#roleVerifier" + ] + } + } + }, + "roleAdmin": { + "type": "token", + "description": "Admin role. Highest level of access, can perform all actions." + }, + "roleModerator": { + "type": "token", + "description": "Moderator role. Can perform most actions." + }, + "roleTriage": { + "type": "token", + "description": "Triage role. Mostly intended for monitoring and escalating issues." + }, + "roleVerifier": { + "type": "token", + "description": "Verifier role. Only allowed to issue verifications." + } + } +} diff --git a/package.json b/package.json index 4fe109848e..b48cbdedbc 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,7 @@ }, "scripts": { "prepare": "is-ci || husky", - "postinstall": "pnpm intl:compile-if-needed", + "postinstall": "lex install --ci && pnpm lexicons:generate && pnpm intl:compile-if-needed", "prebuild": "EXPO_NO_GIT_STATUS=1 expo prebuild --clean", "android": "expo run:android --variant debugOptimized", "android:prod": "expo run:android --variant release", @@ -62,6 +62,8 @@ "lint": "oxlint --quiet src modules", "lint-native": "swiftlint ./modules && ktlint ./modules", "lint-native:fix": "swiftlint --fix ./modules && ktlint --format ./modules", + "lexicons:generate": "lex build --clear --index-file", + "lexicons:update": "lex install --update", "typecheck": "pnpm run typecheck:ios && pnpm run typecheck:android && pnpm run typecheck:web", "typecheck:ios": "tsc --project ./tsconfig.check.ios.json", "typecheck:android": "tsc --project ./tsconfig.check.android.json", @@ -98,6 +100,9 @@ "dependencies": { "@atproto/api": "0.20.34", "@atproto/common-web": "0.5.6", + "@atproto/lex": "0.2.2", + "@atproto/lex-client": "0.2.4", + "@atproto/lex-password-session": "0.1.7", "@atproto/syntax": "0.7.2", "@bitdrift/react-native": "^0.6.8", "@braintree/sanitize-url": "^6.0.2", @@ -109,6 +114,8 @@ "@bsky.app/expo-translate-text": "^0.2.9", "@bsky.app/peek-menu": "^0.3.2", "@bsky.app/react-native-uitextview": "^2.5.0", + "@bsky.app/react-native-mmkv": "2.12.5", + "@bsky.app/sdk": "file:../bsky/packages/sdk", "@bsky.app/sift": "^0.3.9", "@bsky.app/tapper": "^0.6.1", "@bsky.app/video": "0.3.6", @@ -332,7 +339,7 @@ "^await-lock$": "/node_modules/await-lock/build/AwaitLock.js" }, "transformIgnorePatterns": [ - "node_modules/(?!((jest-)?react-native|@react-native(-community)?)|expo(nent)?|@expo(nent)?/.*|@expo-google-fonts/.*|react-navigation|nanoid|@react-navigation/.*|@unimodules/.*|unimodules|sentry-expo|native-base|normalize-url|react-native-svg|@sentry/.*|sentry-expo|bcp-47-match|@atproto/.*|multiformats|uint8arrays|@ipld/.*|cborg|await-lock)" + "node_modules/(?!((jest-)?react-native|@react-native(-community)?)|expo(nent)?|@expo(nent)?/.*|@expo-google-fonts/.*|react-navigation|nanoid|@react-navigation/.*|@unimodules/.*|unimodules|sentry-expo|native-base|normalize-url|react-native-svg|@sentry/.*|sentry-expo|bcp-47-match|@atproto/.*|@bsky.app/sdk|tlds|multiformats|uint8arrays|@ipld/.*|cborg|await-lock)" ], "modulePathIgnorePatterns": [ "__tests__/.*/__mocks__", diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 516406cd36..e15b9c89c5 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -4,6 +4,9 @@ strictPeerDependencies: false # default: false trustPolicy: 'no-downgrade' # default: off trustPolicyIgnoreAfter: 10080 # 7 days, default: undefined overrides: + '@atproto/lex-schema': '0.2.2' + '@atproto/lex-data': '0.1.5' + '@atproto/lex-client': '0.2.4' '@react-native/babel-preset': '0.81.5' '@react-native/normalize-colors': '0.81.5' '@expo/image-utils': '0.8.12' @@ -16,6 +19,7 @@ overrides: 'react-native-screens': '4.24.0' allowBuilds: '@sentry/cli': true + core-js: false 'core-js-pure': true 'esbuild': true 'unrs-resolver': true