@atproto/bsky 0.0.28 → 0.0.30

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (303) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/LICENSE.txt +1 -1
  3. package/dist/api/app/bsky/feed/getAuthorFeed.d.ts +1 -0
  4. package/dist/auto-moderator/index.d.ts +1 -14
  5. package/dist/context.d.ts +0 -3
  6. package/dist/db/index.js +43762 -12377
  7. package/dist/db/index.js.map +3 -3
  8. package/dist/db/pagination.d.ts +1 -0
  9. package/dist/index.d.ts +0 -4
  10. package/dist/index.js +2422 -2135
  11. package/dist/index.js.map +3 -3
  12. package/dist/indexer/config.d.ts +0 -8
  13. package/dist/lexicon/index.d.ts +0 -2
  14. package/dist/lexicon/lexicons.d.ts +134 -52
  15. package/dist/lexicon/types/app/bsky/actor/defs.d.ts +1 -0
  16. package/dist/lexicon/types/app/bsky/actor/getPreferences.d.ts +2 -2
  17. package/dist/lexicon/types/app/bsky/actor/getProfile.d.ts +2 -2
  18. package/dist/lexicon/types/app/bsky/actor/getProfiles.d.ts +2 -2
  19. package/dist/lexicon/types/app/bsky/actor/getSuggestions.d.ts +2 -2
  20. package/dist/lexicon/types/app/bsky/actor/searchActors.d.ts +2 -2
  21. package/dist/lexicon/types/app/bsky/actor/searchActorsTypeahead.d.ts +2 -2
  22. package/dist/lexicon/types/app/bsky/feed/describeFeedGenerator.d.ts +2 -2
  23. package/dist/lexicon/types/app/bsky/feed/getActorFeeds.d.ts +2 -2
  24. package/dist/lexicon/types/app/bsky/feed/getActorLikes.d.ts +2 -2
  25. package/dist/lexicon/types/app/bsky/feed/getAuthorFeed.d.ts +2 -2
  26. package/dist/lexicon/types/app/bsky/feed/getFeed.d.ts +2 -2
  27. package/dist/lexicon/types/app/bsky/feed/getFeedGenerator.d.ts +2 -2
  28. package/dist/lexicon/types/app/bsky/feed/getFeedGenerators.d.ts +2 -2
  29. package/dist/lexicon/types/app/bsky/feed/getFeedSkeleton.d.ts +2 -2
  30. package/dist/lexicon/types/app/bsky/feed/getLikes.d.ts +2 -2
  31. package/dist/lexicon/types/app/bsky/feed/getListFeed.d.ts +2 -2
  32. package/dist/lexicon/types/app/bsky/feed/getPostThread.d.ts +2 -2
  33. package/dist/lexicon/types/app/bsky/feed/getPosts.d.ts +2 -2
  34. package/dist/lexicon/types/app/bsky/feed/getRepostedBy.d.ts +2 -2
  35. package/dist/lexicon/types/app/bsky/feed/getSuggestedFeeds.d.ts +2 -2
  36. package/dist/lexicon/types/app/bsky/feed/getTimeline.d.ts +2 -2
  37. package/dist/lexicon/types/app/bsky/feed/searchPosts.d.ts +2 -2
  38. package/dist/lexicon/types/app/bsky/graph/getBlocks.d.ts +2 -2
  39. package/dist/lexicon/types/app/bsky/graph/getFollowers.d.ts +2 -2
  40. package/dist/lexicon/types/app/bsky/graph/getFollows.d.ts +2 -2
  41. package/dist/lexicon/types/app/bsky/graph/getList.d.ts +2 -2
  42. package/dist/lexicon/types/app/bsky/graph/getListBlocks.d.ts +2 -2
  43. package/dist/lexicon/types/app/bsky/graph/getListMutes.d.ts +2 -2
  44. package/dist/lexicon/types/app/bsky/graph/getLists.d.ts +2 -2
  45. package/dist/lexicon/types/app/bsky/graph/getMutes.d.ts +2 -2
  46. package/dist/lexicon/types/app/bsky/graph/getRelationships.d.ts +2 -2
  47. package/dist/lexicon/types/app/bsky/graph/getSuggestedFollowsByActor.d.ts +2 -2
  48. package/dist/lexicon/types/app/bsky/notification/getUnreadCount.d.ts +2 -2
  49. package/dist/lexicon/types/app/bsky/notification/listNotifications.d.ts +2 -2
  50. package/dist/lexicon/types/app/bsky/unspecced/getPopularFeedGenerators.d.ts +2 -2
  51. package/dist/lexicon/types/app/bsky/unspecced/getTaggedSuggestions.d.ts +2 -2
  52. package/dist/lexicon/types/app/bsky/unspecced/searchActorsSkeleton.d.ts +2 -2
  53. package/dist/lexicon/types/app/bsky/unspecced/searchPostsSkeleton.d.ts +2 -2
  54. package/dist/lexicon/types/com/atproto/admin/createCommunicationTemplate.d.ts +2 -2
  55. package/dist/lexicon/types/com/atproto/admin/defs.d.ts +2 -2
  56. package/dist/lexicon/types/com/atproto/admin/emitModerationEvent.d.ts +2 -2
  57. package/dist/lexicon/types/com/atproto/admin/getAccountInfo.d.ts +2 -2
  58. package/dist/lexicon/types/com/atproto/admin/getAccountInfos.d.ts +2 -2
  59. package/dist/lexicon/types/com/atproto/admin/getInviteCodes.d.ts +2 -2
  60. package/dist/lexicon/types/com/atproto/admin/getModerationEvent.d.ts +2 -2
  61. package/dist/lexicon/types/com/atproto/admin/getRecord.d.ts +2 -2
  62. package/dist/lexicon/types/com/atproto/admin/getRepo.d.ts +2 -2
  63. package/dist/lexicon/types/com/atproto/admin/getSubjectStatus.d.ts +2 -2
  64. package/dist/lexicon/types/com/atproto/admin/listCommunicationTemplates.d.ts +2 -2
  65. package/dist/lexicon/types/com/atproto/admin/queryModerationEvents.d.ts +9 -2
  66. package/dist/lexicon/types/com/atproto/admin/queryModerationStatuses.d.ts +2 -2
  67. package/dist/lexicon/types/com/atproto/admin/searchRepos.d.ts +2 -2
  68. package/dist/lexicon/types/com/atproto/admin/sendEmail.d.ts +2 -2
  69. package/dist/lexicon/types/com/atproto/admin/updateCommunicationTemplate.d.ts +2 -2
  70. package/dist/lexicon/types/com/atproto/admin/updateSubjectStatus.d.ts +2 -2
  71. package/dist/lexicon/types/com/atproto/identity/resolveHandle.d.ts +2 -2
  72. package/dist/lexicon/types/com/atproto/label/queryLabels.d.ts +2 -2
  73. package/dist/lexicon/types/com/atproto/moderation/createReport.d.ts +2 -2
  74. package/dist/lexicon/types/com/atproto/repo/createRecord.d.ts +2 -2
  75. package/dist/lexicon/types/com/atproto/repo/describeRepo.d.ts +2 -2
  76. package/dist/lexicon/types/com/atproto/repo/getRecord.d.ts +2 -2
  77. package/dist/lexicon/types/com/atproto/repo/listRecords.d.ts +2 -2
  78. package/dist/lexicon/types/com/atproto/repo/putRecord.d.ts +2 -2
  79. package/dist/lexicon/types/com/atproto/repo/uploadBlob.d.ts +2 -2
  80. package/dist/lexicon/types/com/atproto/server/createAccount.d.ts +2 -2
  81. package/dist/lexicon/types/com/atproto/server/createAppPassword.d.ts +2 -2
  82. package/dist/lexicon/types/com/atproto/server/createInviteCode.d.ts +2 -2
  83. package/dist/lexicon/types/com/atproto/server/createInviteCodes.d.ts +2 -2
  84. package/dist/lexicon/types/com/atproto/server/createSession.d.ts +2 -2
  85. package/dist/lexicon/types/com/atproto/server/describeServer.d.ts +2 -2
  86. package/dist/lexicon/types/com/atproto/server/getAccountInviteCodes.d.ts +2 -2
  87. package/dist/lexicon/types/com/atproto/server/getSession.d.ts +2 -2
  88. package/dist/lexicon/types/com/atproto/server/listAppPasswords.d.ts +2 -2
  89. package/dist/lexicon/types/com/atproto/server/refreshSession.d.ts +2 -2
  90. package/dist/lexicon/types/com/atproto/server/requestEmailUpdate.d.ts +2 -2
  91. package/dist/lexicon/types/com/atproto/server/reserveSigningKey.d.ts +2 -2
  92. package/dist/lexicon/types/com/atproto/sync/getBlob.d.ts +2 -2
  93. package/dist/lexicon/types/com/atproto/sync/getBlocks.d.ts +2 -2
  94. package/dist/lexicon/types/com/atproto/sync/getCheckout.d.ts +2 -2
  95. package/dist/lexicon/types/com/atproto/sync/getHead.d.ts +2 -2
  96. package/dist/lexicon/types/com/atproto/sync/getLatestCommit.d.ts +2 -2
  97. package/dist/lexicon/types/com/atproto/sync/getRecord.d.ts +2 -2
  98. package/dist/lexicon/types/com/atproto/sync/getRepo.d.ts +2 -2
  99. package/dist/lexicon/types/com/atproto/sync/listBlobs.d.ts +2 -2
  100. package/dist/lexicon/types/com/atproto/sync/listRepos.d.ts +2 -2
  101. package/dist/lexicon/types/com/atproto/temp/checkSignupQueue.d.ts +2 -2
  102. package/dist/lexicon/types/com/atproto/temp/fetchLabels.d.ts +2 -2
  103. package/dist/lexicon/types/com/atproto/temp/importRepo.d.ts +2 -2
  104. package/dist/lexicon/types/com/atproto/temp/transferAccount.d.ts +2 -2
  105. package/dist/services/feed/index.d.ts +2 -1
  106. package/package.json +8 -7
  107. package/src/api/app/bsky/actor/getSuggestions.ts +1 -1
  108. package/src/api/app/bsky/actor/searchActors.ts +1 -0
  109. package/src/api/app/bsky/feed/getActorFeeds.ts +6 -0
  110. package/src/api/app/bsky/feed/getActorLikes.ts +4 -0
  111. package/src/api/app/bsky/feed/getAuthorFeed.ts +16 -4
  112. package/src/api/app/bsky/feed/getFeed.ts +8 -5
  113. package/src/api/app/bsky/feed/getLikes.ts +4 -0
  114. package/src/api/app/bsky/feed/getListFeed.ts +4 -0
  115. package/src/api/app/bsky/feed/getRepostedBy.ts +4 -0
  116. package/src/api/app/bsky/feed/getSuggestedFeeds.ts +1 -1
  117. package/src/api/app/bsky/feed/getTimeline.ts +4 -0
  118. package/src/api/app/bsky/feed/searchPosts.ts +1 -0
  119. package/src/api/app/bsky/graph/getBlocks.ts +7 -0
  120. package/src/api/app/bsky/graph/getFollowers.ts +4 -0
  121. package/src/api/app/bsky/graph/getFollows.ts +4 -0
  122. package/src/api/app/bsky/graph/getList.ts +4 -0
  123. package/src/api/app/bsky/graph/getListBlocks.ts +4 -0
  124. package/src/api/app/bsky/graph/getListMutes.ts +7 -0
  125. package/src/api/app/bsky/graph/getLists.ts +7 -0
  126. package/src/api/app/bsky/graph/getMutes.ts +7 -0
  127. package/src/api/app/bsky/notification/listNotifications.ts +3 -0
  128. package/src/api/app/bsky/unspecced/getPopularFeedGenerators.ts +7 -1
  129. package/src/api/index.ts +0 -6
  130. package/src/auto-moderator/index.ts +9 -176
  131. package/src/context.ts +0 -6
  132. package/src/db/pagination.ts +3 -0
  133. package/src/index.ts +1 -6
  134. package/src/indexer/config.ts +0 -29
  135. package/src/lexicon/index.ts +0 -12
  136. package/src/lexicon/lexicons.ts +382 -173
  137. package/src/lexicon/types/app/bsky/actor/defs.ts +2 -0
  138. package/src/lexicon/types/app/bsky/actor/getPreferences.ts +2 -2
  139. package/src/lexicon/types/app/bsky/actor/getProfile.ts +3 -2
  140. package/src/lexicon/types/app/bsky/actor/getProfiles.ts +2 -2
  141. package/src/lexicon/types/app/bsky/actor/getSuggestions.ts +2 -2
  142. package/src/lexicon/types/app/bsky/actor/profile.ts +3 -0
  143. package/src/lexicon/types/app/bsky/actor/putPreferences.ts +1 -1
  144. package/src/lexicon/types/app/bsky/actor/searchActors.ts +2 -2
  145. package/src/lexicon/types/app/bsky/actor/searchActorsTypeahead.ts +2 -2
  146. package/src/lexicon/types/app/bsky/embed/external.ts +1 -0
  147. package/src/lexicon/types/app/bsky/embed/images.ts +4 -0
  148. package/src/lexicon/types/app/bsky/embed/record.ts +1 -0
  149. package/src/lexicon/types/app/bsky/feed/defs.ts +1 -0
  150. package/src/lexicon/types/app/bsky/feed/describeFeedGenerator.ts +2 -2
  151. package/src/lexicon/types/app/bsky/feed/getActorFeeds.ts +2 -2
  152. package/src/lexicon/types/app/bsky/feed/getActorLikes.ts +2 -2
  153. package/src/lexicon/types/app/bsky/feed/getAuthorFeed.ts +3 -2
  154. package/src/lexicon/types/app/bsky/feed/getFeed.ts +2 -2
  155. package/src/lexicon/types/app/bsky/feed/getFeedGenerator.ts +5 -2
  156. package/src/lexicon/types/app/bsky/feed/getFeedGenerators.ts +2 -2
  157. package/src/lexicon/types/app/bsky/feed/getFeedSkeleton.ts +3 -2
  158. package/src/lexicon/types/app/bsky/feed/getLikes.ts +4 -2
  159. package/src/lexicon/types/app/bsky/feed/getListFeed.ts +3 -2
  160. package/src/lexicon/types/app/bsky/feed/getPostThread.ts +5 -2
  161. package/src/lexicon/types/app/bsky/feed/getPosts.ts +3 -2
  162. package/src/lexicon/types/app/bsky/feed/getRepostedBy.ts +4 -2
  163. package/src/lexicon/types/app/bsky/feed/getSuggestedFeeds.ts +2 -2
  164. package/src/lexicon/types/app/bsky/feed/getTimeline.ts +3 -2
  165. package/src/lexicon/types/app/bsky/feed/post.ts +5 -1
  166. package/src/lexicon/types/app/bsky/feed/searchPosts.ts +2 -2
  167. package/src/lexicon/types/app/bsky/feed/threadgate.ts +1 -0
  168. package/src/lexicon/types/app/bsky/graph/block.ts +1 -0
  169. package/src/lexicon/types/app/bsky/graph/getBlocks.ts +2 -2
  170. package/src/lexicon/types/app/bsky/graph/getFollowers.ts +2 -2
  171. package/src/lexicon/types/app/bsky/graph/getFollows.ts +2 -2
  172. package/src/lexicon/types/app/bsky/graph/getList.ts +3 -2
  173. package/src/lexicon/types/app/bsky/graph/getListBlocks.ts +2 -2
  174. package/src/lexicon/types/app/bsky/graph/getListMutes.ts +2 -2
  175. package/src/lexicon/types/app/bsky/graph/getLists.ts +3 -2
  176. package/src/lexicon/types/app/bsky/graph/getMutes.ts +2 -2
  177. package/src/lexicon/types/app/bsky/graph/getRelationships.ts +4 -2
  178. package/src/lexicon/types/app/bsky/graph/getSuggestedFollowsByActor.ts +2 -2
  179. package/src/lexicon/types/app/bsky/graph/list.ts +1 -0
  180. package/src/lexicon/types/app/bsky/graph/listblock.ts +1 -0
  181. package/src/lexicon/types/app/bsky/graph/listitem.ts +2 -0
  182. package/src/lexicon/types/app/bsky/graph/muteActor.ts +1 -1
  183. package/src/lexicon/types/app/bsky/graph/muteActorList.ts +1 -1
  184. package/src/lexicon/types/app/bsky/graph/unmuteActor.ts +1 -1
  185. package/src/lexicon/types/app/bsky/graph/unmuteActorList.ts +1 -1
  186. package/src/lexicon/types/app/bsky/notification/getUnreadCount.ts +2 -2
  187. package/src/lexicon/types/app/bsky/notification/listNotifications.ts +2 -2
  188. package/src/lexicon/types/app/bsky/notification/registerPush.ts +1 -1
  189. package/src/lexicon/types/app/bsky/notification/updateSeen.ts +1 -1
  190. package/src/lexicon/types/app/bsky/richtext/facet.ts +5 -4
  191. package/src/lexicon/types/app/bsky/unspecced/getPopularFeedGenerators.ts +2 -2
  192. package/src/lexicon/types/app/bsky/unspecced/getTaggedSuggestions.ts +2 -2
  193. package/src/lexicon/types/app/bsky/unspecced/searchActorsSkeleton.ts +2 -2
  194. package/src/lexicon/types/app/bsky/unspecced/searchPostsSkeleton.ts +2 -2
  195. package/src/lexicon/types/com/atproto/admin/createCommunicationTemplate.ts +2 -2
  196. package/src/lexicon/types/com/atproto/admin/defs.ts +2 -0
  197. package/src/lexicon/types/com/atproto/admin/deleteAccount.ts +1 -1
  198. package/src/lexicon/types/com/atproto/admin/deleteCommunicationTemplate.ts +1 -1
  199. package/src/lexicon/types/com/atproto/admin/disableAccountInvites.ts +1 -1
  200. package/src/lexicon/types/com/atproto/admin/disableInviteCodes.ts +1 -1
  201. package/src/lexicon/types/com/atproto/admin/emitModerationEvent.ts +2 -2
  202. package/src/lexicon/types/com/atproto/admin/enableAccountInvites.ts +1 -1
  203. package/src/lexicon/types/com/atproto/admin/getAccountInfo.ts +2 -2
  204. package/src/lexicon/types/com/atproto/admin/getAccountInfos.ts +2 -2
  205. package/src/lexicon/types/com/atproto/admin/getInviteCodes.ts +2 -2
  206. package/src/lexicon/types/com/atproto/admin/getModerationEvent.ts +2 -2
  207. package/src/lexicon/types/com/atproto/admin/getRecord.ts +2 -2
  208. package/src/lexicon/types/com/atproto/admin/getRepo.ts +2 -2
  209. package/src/lexicon/types/com/atproto/admin/getSubjectStatus.ts +2 -2
  210. package/src/lexicon/types/com/atproto/admin/listCommunicationTemplates.ts +2 -2
  211. package/src/lexicon/types/com/atproto/admin/queryModerationEvents.ts +15 -2
  212. package/src/lexicon/types/com/atproto/admin/queryModerationStatuses.ts +2 -2
  213. package/src/lexicon/types/com/atproto/admin/searchRepos.ts +2 -2
  214. package/src/lexicon/types/com/atproto/admin/sendEmail.ts +2 -2
  215. package/src/lexicon/types/com/atproto/admin/updateAccountEmail.ts +1 -1
  216. package/src/lexicon/types/com/atproto/admin/updateAccountHandle.ts +1 -1
  217. package/src/lexicon/types/com/atproto/admin/updateCommunicationTemplate.ts +2 -2
  218. package/src/lexicon/types/com/atproto/admin/updateSubjectStatus.ts +2 -2
  219. package/src/lexicon/types/com/atproto/identity/resolveHandle.ts +2 -2
  220. package/src/lexicon/types/com/atproto/identity/updateHandle.ts +2 -1
  221. package/src/lexicon/types/com/atproto/label/queryLabels.ts +2 -2
  222. package/src/lexicon/types/com/atproto/label/subscribeLabels.ts +1 -1
  223. package/src/lexicon/types/com/atproto/moderation/createReport.ts +3 -2
  224. package/src/lexicon/types/com/atproto/repo/applyWrites.ts +7 -6
  225. package/src/lexicon/types/com/atproto/repo/createRecord.ts +6 -6
  226. package/src/lexicon/types/com/atproto/repo/deleteRecord.ts +3 -3
  227. package/src/lexicon/types/com/atproto/repo/describeRepo.ts +5 -2
  228. package/src/lexicon/types/com/atproto/repo/getRecord.ts +3 -3
  229. package/src/lexicon/types/com/atproto/repo/listRecords.ts +2 -2
  230. package/src/lexicon/types/com/atproto/repo/putRecord.ts +6 -6
  231. package/src/lexicon/types/com/atproto/repo/uploadBlob.ts +2 -2
  232. package/src/lexicon/types/com/atproto/server/confirmEmail.ts +1 -1
  233. package/src/lexicon/types/com/atproto/server/createAccount.ts +10 -2
  234. package/src/lexicon/types/com/atproto/server/createAppPassword.ts +3 -2
  235. package/src/lexicon/types/com/atproto/server/createInviteCode.ts +2 -2
  236. package/src/lexicon/types/com/atproto/server/createInviteCodes.ts +2 -2
  237. package/src/lexicon/types/com/atproto/server/createSession.ts +2 -2
  238. package/src/lexicon/types/com/atproto/server/deleteAccount.ts +1 -1
  239. package/src/lexicon/types/com/atproto/server/deleteSession.ts +1 -1
  240. package/src/lexicon/types/com/atproto/server/describeServer.ts +5 -2
  241. package/src/lexicon/types/com/atproto/server/getAccountInviteCodes.ts +3 -2
  242. package/src/lexicon/types/com/atproto/server/getSession.ts +2 -2
  243. package/src/lexicon/types/com/atproto/server/listAppPasswords.ts +2 -2
  244. package/src/lexicon/types/com/atproto/server/refreshSession.ts +2 -2
  245. package/src/lexicon/types/com/atproto/server/requestAccountDelete.ts +1 -1
  246. package/src/lexicon/types/com/atproto/server/requestEmailConfirmation.ts +1 -1
  247. package/src/lexicon/types/com/atproto/server/requestEmailUpdate.ts +2 -2
  248. package/src/lexicon/types/com/atproto/server/requestPasswordReset.ts +1 -1
  249. package/src/lexicon/types/com/atproto/server/reserveSigningKey.ts +4 -4
  250. package/src/lexicon/types/com/atproto/server/resetPassword.ts +1 -1
  251. package/src/lexicon/types/com/atproto/server/revokeAppPassword.ts +1 -1
  252. package/src/lexicon/types/com/atproto/server/updateEmail.ts +1 -1
  253. package/src/lexicon/types/com/atproto/sync/getBlob.ts +3 -3
  254. package/src/lexicon/types/com/atproto/sync/getBlocks.ts +2 -2
  255. package/src/lexicon/types/com/atproto/sync/getCheckout.ts +2 -2
  256. package/src/lexicon/types/com/atproto/sync/getHead.ts +2 -2
  257. package/src/lexicon/types/com/atproto/sync/getLatestCommit.ts +2 -2
  258. package/src/lexicon/types/com/atproto/sync/getRecord.ts +3 -2
  259. package/src/lexicon/types/com/atproto/sync/getRepo.ts +3 -3
  260. package/src/lexicon/types/com/atproto/sync/listBlobs.ts +2 -2
  261. package/src/lexicon/types/com/atproto/sync/listRepos.ts +3 -2
  262. package/src/lexicon/types/com/atproto/sync/notifyOfUpdate.ts +2 -2
  263. package/src/lexicon/types/com/atproto/sync/requestCrawl.ts +2 -2
  264. package/src/lexicon/types/com/atproto/sync/subscribeRepos.ts +17 -5
  265. package/src/lexicon/types/com/atproto/temp/checkSignupQueue.ts +2 -2
  266. package/src/lexicon/types/com/atproto/temp/fetchLabels.ts +2 -2
  267. package/src/lexicon/types/com/atproto/temp/importRepo.ts +2 -2
  268. package/src/lexicon/types/com/atproto/temp/pushBlob.ts +1 -1
  269. package/src/lexicon/types/com/atproto/temp/requestPhoneVerification.ts +1 -1
  270. package/src/lexicon/types/com/atproto/temp/transferAccount.ts +2 -2
  271. package/src/logger.ts +32 -0
  272. package/src/services/feed/index.ts +10 -4
  273. package/src/services/feed/views.ts +3 -1
  274. package/tests/auto-moderator/labeler.test.ts +2 -0
  275. package/tests/feed-generation.test.ts +0 -6
  276. package/tests/views/author-feed.test.ts +29 -9
  277. package/tests/views/notifications.test.ts +9 -0
  278. package/tests/views/timeline.test.ts +8 -0
  279. package/dist/api/app/bsky/feed/describeFeedGenerator.d.ts +0 -3
  280. package/dist/api/app/bsky/feed/getFeedSkeleton.d.ts +0 -3
  281. package/dist/api/app/bsky/unspecced/getTimelineSkeleton.d.ts +0 -3
  282. package/dist/auto-moderator/abyss.d.ts +0 -48
  283. package/dist/auto-moderator/fuzzy-matcher.d.ts +0 -14
  284. package/dist/feed-gen/bsky-team.d.ts +0 -3
  285. package/dist/feed-gen/hot-classic.d.ts +0 -3
  286. package/dist/feed-gen/index.d.ts +0 -2
  287. package/dist/feed-gen/mutuals.d.ts +0 -3
  288. package/dist/feed-gen/types.d.ts +0 -15
  289. package/dist/lexicon/types/app/bsky/unspecced/getTimelineSkeleton.d.ts +0 -35
  290. package/src/api/app/bsky/feed/describeFeedGenerator.ts +0 -21
  291. package/src/api/app/bsky/feed/getFeedSkeleton.ts +0 -30
  292. package/src/api/app/bsky/unspecced/getTimelineSkeleton.ts +0 -26
  293. package/src/auto-moderator/abyss.ts +0 -114
  294. package/src/auto-moderator/fuzzy-matcher.ts +0 -126
  295. package/src/feed-gen/bsky-team.ts +0 -42
  296. package/src/feed-gen/hot-classic.ts +0 -55
  297. package/src/feed-gen/index.ts +0 -17
  298. package/src/feed-gen/mutuals.ts +0 -57
  299. package/src/feed-gen/types.ts +0 -32
  300. package/src/lexicon/types/app/bsky/unspecced/getTimelineSkeleton.ts +0 -49
  301. package/tests/algos/hot-classic.test.ts +0 -87
  302. package/tests/auto-moderator/fuzzy-matcher.test.ts +0 -163
  303. package/tests/auto-moderator/takedowns.test.ts +0 -202
@@ -1,126 +0,0 @@
1
- import { dedupeStrs } from '@atproto/common'
2
- import * as ui8 from 'uint8arrays'
3
-
4
- export interface TextFlagger {
5
- getMatches(string: string): string[]
6
- }
7
-
8
- export class FuzzyMatcher implements TextFlagger {
9
- private bannedWords: Set<string>
10
- private falsePositives: Set<string>
11
-
12
- constructor(bannedWords: string[], falsePositives: string[] = []) {
13
- this.bannedWords = new Set(bannedWords.map((word) => word.toLowerCase()))
14
- this.falsePositives = new Set(
15
- falsePositives.map((word) => word.toLowerCase()),
16
- )
17
- }
18
-
19
- static fromB64(bannedB64: string, falsePositivesB64?: string) {
20
- return new FuzzyMatcher(
21
- decode(bannedB64),
22
- falsePositivesB64 ? decode(falsePositivesB64) : undefined,
23
- )
24
- }
25
-
26
- private normalize(domain: string): string[] {
27
- const withoutSymbols = domain.replace(/[\W_]+/g, '') // Remove non-alphanumeric characters
28
- const lowercase = withoutSymbols.toLowerCase()
29
-
30
- // Replace common leetspeak characters
31
- const leetSpeakReplacements: { [key: string]: string[] } = {
32
- '0': ['o'],
33
- '8': ['b'],
34
- '3': ['e'],
35
- '4': ['a'],
36
- '6': ['g'],
37
- '1': ['i', 'l'],
38
- '5': ['s'],
39
- '7': ['t'],
40
- }
41
-
42
- return this.generatePermutations(lowercase, leetSpeakReplacements)
43
- }
44
-
45
- private generatePermutations(
46
- domain: string,
47
- leetSpeakReplacements: { [key: string]: string[] },
48
- ): string[] {
49
- const results: string[] = []
50
-
51
- const leetChars = Object.keys(leetSpeakReplacements)
52
- const firstLeetCharIndex = [...domain].findIndex((char) =>
53
- leetChars.includes(char),
54
- )
55
-
56
- if (firstLeetCharIndex === -1) {
57
- // No leetspeak characters left in the string
58
- results.push(domain)
59
- } else {
60
- const char = domain[firstLeetCharIndex]
61
- const beforeChar = domain.slice(0, firstLeetCharIndex)
62
- const afterChar = domain.slice(firstLeetCharIndex + 1)
63
-
64
- // For each replacement, generate all possible combinations
65
- for (const replacement of leetSpeakReplacements[char]) {
66
- const replaced = beforeChar + replacement + afterChar
67
-
68
- // Recursively generate all permutations for the rest of the string
69
- const otherPermutations = this.generatePermutations(
70
- replaced,
71
- leetSpeakReplacements,
72
- )
73
-
74
- // Add these permutations to the results
75
- results.push(...otherPermutations)
76
- }
77
- }
78
-
79
- return dedupeStrs(results)
80
- }
81
-
82
- public getMatches(domain: string): string[] {
83
- const normalizedDomains = this.normalize(domain)
84
-
85
- const foundUnacceptableWords: string[] = []
86
-
87
- for (const normalizedDomain of normalizedDomains) {
88
- for (const word of this.bannedWords) {
89
- const match = normalizedDomain.indexOf(word)
90
- if (match > -1) {
91
- let isFalsePositive = false
92
- for (const falsePositive of this.falsePositives) {
93
- const s_fp = falsePositive.indexOf(word)
94
- const s_nd = match - s_fp
95
- const wordToMatch = normalizedDomain.slice(
96
- s_nd,
97
- s_nd + falsePositive.length,
98
- )
99
- if (wordToMatch === falsePositive) {
100
- isFalsePositive = true
101
- break
102
- }
103
- }
104
-
105
- if (!isFalsePositive) {
106
- foundUnacceptableWords.push(word)
107
- }
108
- }
109
- }
110
- }
111
-
112
- if (foundUnacceptableWords.length > 0) {
113
- return foundUnacceptableWords
114
- }
115
-
116
- return []
117
- }
118
- }
119
-
120
- export const decode = (encoded: string): string[] => {
121
- return ui8.toString(ui8.fromString(encoded, 'base64'), 'utf8').split(',')
122
- }
123
-
124
- export const encode = (words: string[]): string => {
125
- return ui8.toString(ui8.fromString(words.join(','), 'utf8'), 'base64')
126
- }
@@ -1,42 +0,0 @@
1
- import { NotEmptyArray } from '@atproto/common'
2
- import { QueryParams as SkeletonParams } from '../lexicon/types/app/bsky/feed/getFeedSkeleton'
3
- import AppContext from '../context'
4
- import { paginate } from '../db/pagination'
5
- import { AlgoHandler, AlgoResponse } from './types'
6
- import { FeedKeyset } from '../api/app/bsky/util/feed'
7
-
8
- const BSKY_TEAM: NotEmptyArray<string> = [
9
- 'did:plc:z72i7hdynmk6r22z27h6tvur', // @bsky.app
10
- 'did:plc:ewvi7nxzyoun6zhxrhs64oiz', // @atproto.com
11
- 'did:plc:eon2iu7v3x2ukgxkqaf7e5np', // @safety.bsky.app
12
- ]
13
-
14
- const handler: AlgoHandler = async (
15
- ctx: AppContext,
16
- params: SkeletonParams,
17
- _viewer: string | null,
18
- ): Promise<AlgoResponse> => {
19
- const { limit = 50, cursor } = params
20
- const db = ctx.db.getReplica('feed')
21
- const feedService = ctx.services.feed(db)
22
-
23
- const { ref } = db.db.dynamic
24
-
25
- const postsQb = feedService
26
- .selectPostQb()
27
- .where('post.creator', 'in', BSKY_TEAM)
28
-
29
- const keyset = new FeedKeyset(ref('sortAt'), ref('cid'))
30
-
31
- let feedQb = db.db.selectFrom(postsQb.as('feed_items')).selectAll()
32
- feedQb = paginate(feedQb, { limit, cursor, keyset })
33
-
34
- const feedItems = await feedQb.execute()
35
-
36
- return {
37
- feedItems,
38
- cursor: keyset.packFromResult(feedItems),
39
- }
40
- }
41
-
42
- export default handler
@@ -1,55 +0,0 @@
1
- import AppContext from '../context'
2
- import { NotEmptyArray } from '@atproto/common'
3
- import { QueryParams as SkeletonParams } from '../lexicon/types/app/bsky/feed/getFeedSkeleton'
4
- import { paginate } from '../db/pagination'
5
- import { AlgoHandler, AlgoResponse } from './types'
6
- import { FeedKeyset } from '../api/app/bsky/util/feed'
7
- import { valuesList } from '../db/util'
8
-
9
- const NO_WHATS_HOT_LABELS: NotEmptyArray<string> = ['!no-promote']
10
-
11
- const handler: AlgoHandler = async (
12
- ctx: AppContext,
13
- params: SkeletonParams,
14
- _viewer: string | null,
15
- ): Promise<AlgoResponse> => {
16
- const { limit = 50, cursor } = params
17
- const db = ctx.db.getReplica('feed')
18
- const feedService = ctx.services.feed(db)
19
-
20
- const { ref } = db.db.dynamic
21
-
22
- const postsQb = feedService
23
- .selectPostQb()
24
- .leftJoin('post_agg', 'post_agg.uri', 'post.uri')
25
- .leftJoin('post_embed_record', 'post_embed_record.postUri', 'post.uri')
26
- .where('post_agg.likeCount', '>=', 12)
27
- .where('post.replyParent', 'is', null)
28
- .whereNotExists((qb) =>
29
- qb
30
- .selectFrom('label')
31
- .selectAll()
32
- .whereRef('val', 'in', valuesList(NO_WHATS_HOT_LABELS))
33
- .where('neg', '=', false)
34
- .where((clause) =>
35
- clause
36
- .whereRef('label.uri', '=', ref('post.creator'))
37
- .orWhereRef('label.uri', '=', ref('post.uri'))
38
- .orWhereRef('label.uri', '=', ref('post_embed_record.embedUri')),
39
- ),
40
- )
41
-
42
- const keyset = new FeedKeyset(ref('sortAt'), ref('cid'))
43
-
44
- let feedQb = db.db.selectFrom(postsQb.as('feed_items')).selectAll()
45
- feedQb = paginate(feedQb, { limit, cursor, keyset })
46
-
47
- const feedItems = await feedQb.execute()
48
-
49
- return {
50
- feedItems,
51
- cursor: keyset.packFromResult(feedItems),
52
- }
53
- }
54
-
55
- export default handler
@@ -1,17 +0,0 @@
1
- import { AtUri } from '@atproto/syntax'
2
- import { ids } from '../lexicon/lexicons'
3
- import bskyTeam from './bsky-team'
4
- import hotClassic from './hot-classic'
5
- import mutuals from './mutuals'
6
- import { MountedAlgos } from './types'
7
-
8
- const feedgenUri = (did, name) =>
9
- AtUri.make(did, ids.AppBskyFeedGenerator, name).toString()
10
-
11
- // These are custom algorithms that will be mounted directly onto an AppView
12
- // Feel free to remove, update to your own, or serve the following logic at a record that you control
13
- export const makeAlgos = (did: string): MountedAlgos => ({
14
- [feedgenUri(did, 'bsky-team')]: bskyTeam,
15
- [feedgenUri(did, 'hot-classic')]: hotClassic,
16
- [feedgenUri(did, 'mutuals')]: mutuals,
17
- })
@@ -1,57 +0,0 @@
1
- import { QueryParams as SkeletonParams } from '../lexicon/types/app/bsky/feed/getFeedSkeleton'
2
- import AppContext from '../context'
3
- import { paginate } from '../db/pagination'
4
- import { AlgoHandler, AlgoResponse } from './types'
5
- import { FeedKeyset, getFeedDateThreshold } from '../api/app/bsky/util/feed'
6
- import { AuthRequiredError } from '@atproto/xrpc-server'
7
-
8
- const handler: AlgoHandler = async (
9
- ctx: AppContext,
10
- params: SkeletonParams,
11
- viewer: string | null,
12
- ): Promise<AlgoResponse> => {
13
- if (!viewer) {
14
- throw new AuthRequiredError('This feed requires being logged-in')
15
- }
16
-
17
- const { limit = 50, cursor } = params
18
- const db = ctx.db.getReplica('feed')
19
- const feedService = ctx.services.feed(db)
20
- const { ref } = db.db.dynamic
21
-
22
- const mutualsSubquery = db.db
23
- .selectFrom('follow')
24
- .where('follow.creator', '=', viewer)
25
- .whereExists((qb) =>
26
- qb
27
- .selectFrom('follow as follow_inner')
28
- .whereRef('follow_inner.creator', '=', 'follow.subjectDid')
29
- .where('follow_inner.subjectDid', '=', viewer)
30
- .selectAll(),
31
- )
32
- .select('follow.subjectDid')
33
-
34
- const keyset = new FeedKeyset(ref('feed_item.sortAt'), ref('feed_item.cid'))
35
- const sortFrom = keyset.unpack(cursor)?.primary
36
-
37
- let feedQb = feedService
38
- .selectFeedItemQb()
39
- .where('feed_item.type', '=', 'post') // ensures originatorDid is post.creator
40
- .where((qb) =>
41
- qb
42
- .where('originatorDid', '=', viewer)
43
- .orWhere('originatorDid', 'in', mutualsSubquery),
44
- )
45
- .where('feed_item.sortAt', '>', getFeedDateThreshold(sortFrom))
46
-
47
- feedQb = paginate(feedQb, { limit, cursor, keyset })
48
-
49
- const feedItems = await feedQb.execute()
50
-
51
- return {
52
- feedItems,
53
- cursor: keyset.packFromResult(feedItems),
54
- }
55
- }
56
-
57
- export default handler
@@ -1,32 +0,0 @@
1
- import AppContext from '../context'
2
- import { SkeletonFeedPost } from '../lexicon/types/app/bsky/feed/defs'
3
- import { QueryParams as SkeletonParams } from '../lexicon/types/app/bsky/feed/getFeedSkeleton'
4
- import { FeedRow } from '../services/feed'
5
-
6
- export type AlgoResponse = {
7
- feedItems: FeedRow[]
8
- resHeaders?: Record<string, string>
9
- cursor?: string
10
- }
11
-
12
- export type AlgoHandler = (
13
- ctx: AppContext,
14
- params: SkeletonParams,
15
- viewer: string | null,
16
- ) => Promise<AlgoResponse>
17
-
18
- export type MountedAlgos = Record<string, AlgoHandler>
19
-
20
- export const toSkeletonItem = (feedItem: {
21
- uri: string
22
- postUri: string
23
- }): SkeletonFeedPost => ({
24
- post: feedItem.postUri,
25
- reason:
26
- feedItem.uri === feedItem.postUri
27
- ? undefined
28
- : {
29
- $type: 'app.bsky.feed.defs#skeletonReasonRepost',
30
- repost: feedItem.uri,
31
- },
32
- })
@@ -1,49 +0,0 @@
1
- /**
2
- * GENERATED CODE - DO NOT MODIFY
3
- */
4
- import express from 'express'
5
- import { ValidationResult, BlobRef } from '@atproto/lexicon'
6
- import { lexicons } from '../../../../lexicons'
7
- import { isObj, hasProp } from '../../../../util'
8
- import { CID } from 'multiformats/cid'
9
- import { HandlerAuth } from '@atproto/xrpc-server'
10
- import * as AppBskyFeedDefs from '../feed/defs'
11
-
12
- export interface QueryParams {
13
- limit: number
14
- cursor?: string
15
- }
16
-
17
- export type InputSchema = undefined
18
-
19
- export interface OutputSchema {
20
- cursor?: string
21
- feed: AppBskyFeedDefs.SkeletonFeedPost[]
22
- [k: string]: unknown
23
- }
24
-
25
- export type HandlerInput = undefined
26
-
27
- export interface HandlerSuccess {
28
- encoding: 'application/json'
29
- body: OutputSchema
30
- headers?: { [key: string]: string }
31
- }
32
-
33
- export interface HandlerError {
34
- status: number
35
- message?: string
36
- error?: 'UnknownFeed'
37
- }
38
-
39
- export type HandlerOutput = HandlerError | HandlerSuccess
40
- export type HandlerReqCtx<HA extends HandlerAuth = never> = {
41
- auth: HA
42
- params: QueryParams
43
- input: HandlerInput
44
- req: express.Request
45
- res: express.Response
46
- }
47
- export type Handler<HA extends HandlerAuth = never> = (
48
- ctx: HandlerReqCtx<HA>,
49
- ) => Promise<HandlerOutput> | HandlerOutput
@@ -1,87 +0,0 @@
1
- import AtpAgent, { AtUri } from '@atproto/api'
2
- import { TestNetwork, SeedClient, basicSeed } from '@atproto/dev-env'
3
- import { makeAlgos } from '../../src'
4
-
5
- describe('algo hot-classic', () => {
6
- let network: TestNetwork
7
- let agent: AtpAgent
8
- let sc: SeedClient
9
-
10
- // account dids, for convenience
11
- let alice: string
12
- let bob: string
13
-
14
- const feedPublisherDid = 'did:example:feed-publisher'
15
- const feedUri = AtUri.make(
16
- feedPublisherDid,
17
- 'app.bsky.feed.generator',
18
- 'hot-classic',
19
- ).toString()
20
-
21
- beforeAll(async () => {
22
- network = await TestNetwork.create({
23
- dbPostgresSchema: 'bsky_algo_hot_classic',
24
- bsky: { algos: makeAlgos(feedPublisherDid) },
25
- })
26
- agent = new AtpAgent({ service: network.bsky.url })
27
- sc = network.getSeedClient()
28
- await basicSeed(sc)
29
-
30
- alice = sc.dids.alice
31
- bob = sc.dids.bob
32
- await network.processAll()
33
- })
34
-
35
- afterAll(async () => {
36
- await network.close()
37
- })
38
-
39
- it('returns well liked posts', async () => {
40
- const img = await sc.uploadFile(
41
- alice,
42
- '../dev-env/src/seed/img/key-landscape-small.jpg',
43
- 'image/jpeg',
44
- )
45
- const one = await sc.post(alice, 'first post', undefined, [img])
46
- const two = await sc.post(bob, 'bobby boi')
47
- const three = await sc.reply(bob, one.ref, one.ref, 'reply')
48
-
49
- for (let i = 0; i < 12; i++) {
50
- const name = `user${i}`
51
- await sc.createAccount(name, {
52
- handle: `user${i}.test`,
53
- email: `user${i}@test.com`,
54
- password: 'password',
55
- })
56
- await sc.like(sc.dids[name], one.ref)
57
- await sc.like(sc.dids[name], two.ref)
58
- await sc.like(sc.dids[name], three.ref)
59
- }
60
- await network.processAll()
61
-
62
- const res = await agent.api.app.bsky.feed.getFeed(
63
- { feed: feedUri },
64
- { headers: await network.serviceHeaders(alice) },
65
- )
66
- const feedUris = res.data.feed.map((i) => i.post.uri).sort()
67
- const expected = [one.ref.uriStr, two.ref.uriStr].sort()
68
- expect(feedUris).toEqual(expected)
69
- })
70
-
71
- it('paginates', async () => {
72
- const res = await agent.api.app.bsky.feed.getFeed(
73
- { feed: feedUri },
74
- { headers: await network.serviceHeaders(alice) },
75
- )
76
- const first = await agent.api.app.bsky.feed.getFeed(
77
- { feed: feedUri, limit: 1 },
78
- { headers: await network.serviceHeaders(alice) },
79
- )
80
- const second = await agent.api.app.bsky.feed.getFeed(
81
- { feed: feedUri, cursor: first.data.cursor },
82
- { headers: await network.serviceHeaders(alice) },
83
- )
84
-
85
- expect([...first.data.feed, ...second.data.feed]).toEqual(res.data.feed)
86
- })
87
- })
@@ -1,163 +0,0 @@
1
- import { TestNetwork, SeedClient, basicSeed } from '@atproto/dev-env'
2
- import { FuzzyMatcher, encode } from '../../src/auto-moderator/fuzzy-matcher'
3
- import { AtpAgent } from '@atproto/api'
4
- import { ImageInvalidator } from '../../src/image/invalidator'
5
-
6
- describe('fuzzy matcher', () => {
7
- let network: TestNetwork
8
- let agent: AtpAgent
9
- let sc: SeedClient
10
- let fuzzyMatcher: FuzzyMatcher
11
-
12
- let alice: string
13
-
14
- beforeAll(async () => {
15
- network = await TestNetwork.create({
16
- dbPostgresSchema: 'fuzzy_matcher',
17
- bsky: {
18
- imgInvalidator: new NoopInvalidator(),
19
- indexer: {
20
- fuzzyMatchB64: encode(['evil']),
21
- },
22
- },
23
- })
24
- fuzzyMatcher = new FuzzyMatcher(['evil', 'mean', 'bad'], ['baddie'])
25
- agent = network.pds.getClient()
26
- sc = network.getSeedClient()
27
- await basicSeed(sc)
28
- await network.processAll()
29
- alice = sc.dids.alice
30
- })
31
-
32
- afterAll(async () => {
33
- await network.close()
34
- })
35
-
36
- const getAllReports = () => {
37
- return network.ozone.ctx.db.db
38
- .selectFrom('moderation_event')
39
- .where('action', '=', 'com.atproto.admin.defs#modEventReport')
40
- .selectAll()
41
- .orderBy('id', 'asc')
42
- .execute()
43
- }
44
-
45
- it('identifies fuzzy matches', () => {
46
- expect(fuzzyMatcher.getMatches('evil.john.test')).toMatchObject(['evil'])
47
- expect(fuzzyMatcher.getMatches('john.evil.test')).toMatchObject(['evil'])
48
- expect(fuzzyMatcher.getMatches('john.test.evil')).toMatchObject(['evil'])
49
- expect(fuzzyMatcher.getMatches('ev1l.test.john')).toMatchObject(['evil'])
50
- expect(fuzzyMatcher.getMatches('ev-1l.test.john')).toMatchObject(['evil'])
51
- expect(fuzzyMatcher.getMatches('ev-11.test.john')).toMatchObject(['evil'])
52
- expect(fuzzyMatcher.getMatches('ev.-1.l-test.john')).toMatchObject(['evil'])
53
- })
54
-
55
- it('identifies fuzzy false positivies', () => {
56
- expect(fuzzyMatcher.getMatches('john.test')).toHaveLength(0)
57
- expect(fuzzyMatcher.getMatches('good.john.test')).toHaveLength(0)
58
- expect(fuzzyMatcher.getMatches('john.baddie.test')).toHaveLength(0)
59
- })
60
-
61
- it('doesnt label any of the content in the seed', async () => {
62
- const reports = await getAllReports()
63
- expect(reports.length).toBe(0)
64
- })
65
-
66
- it('flags a handle with an unacceptable word', async () => {
67
- await sc.updateHandle(alice, 'evil.test')
68
- await network.processAll()
69
- const reports = await getAllReports()
70
- expect(reports.length).toBe(1)
71
- expect(reports.at(-1)?.subjectDid).toEqual(alice)
72
- })
73
-
74
- it('flags a profile with an unacceptable displayName', async () => {
75
- const res = await agent.api.com.atproto.repo.putRecord(
76
- {
77
- repo: alice,
78
- collection: 'app.bsky.actor.profile',
79
- rkey: 'self',
80
- record: {
81
- displayName: 'evil alice',
82
- },
83
- },
84
- { headers: sc.getHeaders(alice), encoding: 'application/json' },
85
- )
86
- await network.processAll()
87
-
88
- const reports = await getAllReports()
89
- expect(reports.length).toBe(2)
90
- expect(reports.at(-1)?.subjectUri).toEqual(res.data.uri)
91
- expect(reports.at(-1)?.subjectCid).toEqual(res.data.cid)
92
- })
93
-
94
- it('flags a list with an unacceptable name', async () => {
95
- const res = await agent.api.com.atproto.repo.createRecord(
96
- {
97
- repo: alice,
98
- collection: 'app.bsky.graph.list',
99
- rkey: 'list',
100
- record: {
101
- name: 'myevillist',
102
- purpose: 'app.bsky.graph.defs#modList',
103
- createdAt: new Date().toISOString(),
104
- },
105
- },
106
- { headers: sc.getHeaders(alice), encoding: 'application/json' },
107
- )
108
- await network.processAll()
109
-
110
- const reports = await getAllReports()
111
- expect(reports.length).toBe(3)
112
- expect(reports.at(-1)?.subjectUri).toEqual(res.data.uri)
113
- expect(reports.at(-1)?.subjectCid).toEqual(res.data.cid)
114
- })
115
-
116
- it('flags a feed generator with an unacceptable displayName', async () => {
117
- const res = await agent.api.com.atproto.repo.createRecord(
118
- {
119
- repo: alice,
120
- collection: 'app.bsky.feed.generator',
121
- rkey: 'generator',
122
- record: {
123
- did: alice,
124
- displayName: 'myevilfeed',
125
- createdAt: new Date().toISOString(),
126
- },
127
- },
128
- { headers: sc.getHeaders(alice), encoding: 'application/json' },
129
- )
130
- await network.processAll()
131
-
132
- const reports = await getAllReports()
133
- expect(reports.length).toBe(4)
134
- expect(reports.at(-1)?.subjectUri).toEqual(res.data.uri)
135
- expect(reports.at(-1)?.subjectCid).toEqual(res.data.cid)
136
- })
137
-
138
- it('flags a record with an unacceptable rkey', async () => {
139
- const res = await agent.api.com.atproto.repo.createRecord(
140
- {
141
- repo: alice,
142
- collection: 'app.bsky.feed.generator',
143
- rkey: 'evilrkey',
144
- record: {
145
- did: alice,
146
- displayName: 'totally fine feed',
147
- createdAt: new Date().toISOString(),
148
- },
149
- },
150
- { headers: sc.getHeaders(alice), encoding: 'application/json' },
151
- )
152
- await network.processAll()
153
-
154
- const reports = await getAllReports()
155
- expect(reports.length).toBe(5)
156
- expect(reports.at(-1)?.subjectUri).toEqual(res.data.uri)
157
- expect(reports.at(-1)?.subjectCid).toEqual(res.data.cid)
158
- })
159
- })
160
-
161
- class NoopInvalidator implements ImageInvalidator {
162
- async invalidate() {}
163
- }