@atproto/ozone 0.0.2

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 (444) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/LICENSE.txt +7 -0
  3. package/README.md +15 -0
  4. package/babel.config.js +3 -0
  5. package/bin/migration-create.ts +38 -0
  6. package/build.js +18 -0
  7. package/dist/api/admin/emitModerationEvent.d.ts +3 -0
  8. package/dist/api/admin/getModerationEvent.d.ts +3 -0
  9. package/dist/api/admin/getRecord.d.ts +3 -0
  10. package/dist/api/admin/getRepo.d.ts +3 -0
  11. package/dist/api/admin/queryModerationEvents.d.ts +3 -0
  12. package/dist/api/admin/queryModerationStatuses.d.ts +3 -0
  13. package/dist/api/admin/searchRepos.d.ts +3 -0
  14. package/dist/api/admin/util.d.ts +5 -0
  15. package/dist/api/com/atproto/admin/emitModerationEvent.d.ts +3 -0
  16. package/dist/api/com/atproto/admin/getModerationEvent.d.ts +3 -0
  17. package/dist/api/com/atproto/admin/getRecord.d.ts +3 -0
  18. package/dist/api/com/atproto/admin/getRepo.d.ts +3 -0
  19. package/dist/api/com/atproto/admin/queryModerationEvents.d.ts +3 -0
  20. package/dist/api/com/atproto/admin/queryModerationStatuses.d.ts +3 -0
  21. package/dist/api/com/atproto/admin/searchRepos.d.ts +3 -0
  22. package/dist/api/com/atproto/admin/util.d.ts +5 -0
  23. package/dist/api/com/atproto/moderation/createReport.d.ts +3 -0
  24. package/dist/api/com/atproto/moderation/util.d.ts +4 -0
  25. package/dist/api/com/atproto/temp/fetchLabels.d.ts +3 -0
  26. package/dist/api/health.d.ts +3 -0
  27. package/dist/api/index.d.ts +5 -0
  28. package/dist/api/label/queryLabels.d.ts +3 -0
  29. package/dist/api/label/subscribeLabels.d.ts +3 -0
  30. package/dist/api/moderation/createReport.d.ts +3 -0
  31. package/dist/api/moderation/util.d.ts +4 -0
  32. package/dist/api/temp/fetchLabels.d.ts +3 -0
  33. package/dist/api/util.d.ts +2 -0
  34. package/dist/api/well-known.d.ts +3 -0
  35. package/dist/auth-verifier.d.ts +47 -0
  36. package/dist/auth.d.ts +81 -0
  37. package/dist/background.d.ts +13 -0
  38. package/dist/config/config.d.ts +30 -0
  39. package/dist/config/env.d.ts +19 -0
  40. package/dist/config/index.d.ts +3 -0
  41. package/dist/config/secrets.d.ts +8 -0
  42. package/dist/config.d.ts +42 -0
  43. package/dist/context.d.ts +140 -0
  44. package/dist/daemon/config.d.ts +23 -0
  45. package/dist/daemon/context.d.ts +25 -0
  46. package/dist/daemon/event-pusher.d.ts +48 -0
  47. package/dist/daemon/event-reverser.d.ts +16 -0
  48. package/dist/daemon/index.d.ts +13 -0
  49. package/dist/db/index.d.ts +32 -0
  50. package/dist/db/index.js +33707 -0
  51. package/dist/db/index.js.map +7 -0
  52. package/dist/db/migrations/20231219T205730722Z-init.d.ts +3 -0
  53. package/dist/db/migrations/index.d.ts +1 -0
  54. package/dist/db/migrations/provider.d.ts +11 -0
  55. package/dist/db/pagination.d.ts +66 -0
  56. package/dist/db/schema/blob_push_event.d.ts +17 -0
  57. package/dist/db/schema/index.d.ts +10 -0
  58. package/dist/db/schema/label.d.ts +12 -0
  59. package/dist/db/schema/moderation_event.d.ts +22 -0
  60. package/dist/db/schema/moderation_subject_status.d.ts +25 -0
  61. package/dist/db/schema/record_push_event.d.ts +17 -0
  62. package/dist/db/schema/repo_push_event.d.ts +15 -0
  63. package/dist/db/types.d.ts +12 -0
  64. package/dist/error.d.ts +2 -0
  65. package/dist/index.d.ts +27 -0
  66. package/dist/index.js +131818 -0
  67. package/dist/index.js.map +7 -0
  68. package/dist/lexicon/index.d.ts +372 -0
  69. package/dist/lexicon/lexicons.d.ts +7553 -0
  70. package/dist/lexicon/types/app/bsky/actor/defs.d.ts +104 -0
  71. package/dist/lexicon/types/app/bsky/actor/getPreferences.d.ts +31 -0
  72. package/dist/lexicon/types/app/bsky/actor/getProfile.d.ts +29 -0
  73. package/dist/lexicon/types/app/bsky/actor/getProfiles.d.ts +32 -0
  74. package/dist/lexicon/types/app/bsky/actor/getSuggestions.d.ts +34 -0
  75. package/dist/lexicon/types/app/bsky/actor/profile.d.ts +15 -0
  76. package/dist/lexicon/types/app/bsky/actor/putPreferences.d.ts +26 -0
  77. package/dist/lexicon/types/app/bsky/actor/searchActors.d.ts +36 -0
  78. package/dist/lexicon/types/app/bsky/actor/searchActorsTypeahead.d.ts +34 -0
  79. package/dist/lexicon/types/app/bsky/embed/external.d.ts +31 -0
  80. package/dist/lexicon/types/app/bsky/embed/images.d.ts +37 -0
  81. package/dist/lexicon/types/app/bsky/embed/record.d.ts +54 -0
  82. package/dist/lexicon/types/app/bsky/embed/recordWithMedia.d.ts +24 -0
  83. package/dist/lexicon/types/app/bsky/feed/defs.d.ts +151 -0
  84. package/dist/lexicon/types/app/bsky/feed/describeFeedGenerator.d.ts +46 -0
  85. package/dist/lexicon/types/app/bsky/feed/generator.d.ts +18 -0
  86. package/dist/lexicon/types/app/bsky/feed/getActorFeeds.d.ts +35 -0
  87. package/dist/lexicon/types/app/bsky/feed/getActorLikes.d.ts +36 -0
  88. package/dist/lexicon/types/app/bsky/feed/getAuthorFeed.d.ts +37 -0
  89. package/dist/lexicon/types/app/bsky/feed/getFeed.d.ts +36 -0
  90. package/dist/lexicon/types/app/bsky/feed/getFeedGenerator.d.ts +34 -0
  91. package/dist/lexicon/types/app/bsky/feed/getFeedGenerators.d.ts +32 -0
  92. package/dist/lexicon/types/app/bsky/feed/getFeedSkeleton.d.ts +36 -0
  93. package/dist/lexicon/types/app/bsky/feed/getLikes.d.ts +47 -0
  94. package/dist/lexicon/types/app/bsky/feed/getListFeed.d.ts +36 -0
  95. package/dist/lexicon/types/app/bsky/feed/getPostThread.d.ts +38 -0
  96. package/dist/lexicon/types/app/bsky/feed/getPosts.d.ts +32 -0
  97. package/dist/lexicon/types/app/bsky/feed/getRepostedBy.d.ts +38 -0
  98. package/dist/lexicon/types/app/bsky/feed/getSuggestedFeeds.d.ts +34 -0
  99. package/dist/lexicon/types/app/bsky/feed/getTimeline.d.ts +35 -0
  100. package/dist/lexicon/types/app/bsky/feed/like.d.ts +9 -0
  101. package/dist/lexicon/types/app/bsky/feed/post.d.ts +50 -0
  102. package/dist/lexicon/types/app/bsky/feed/repost.d.ts +9 -0
  103. package/dist/lexicon/types/app/bsky/feed/searchPosts.d.ts +37 -0
  104. package/dist/lexicon/types/app/bsky/feed/threadgate.d.ts +28 -0
  105. package/dist/lexicon/types/app/bsky/graph/block.d.ts +8 -0
  106. package/dist/lexicon/types/app/bsky/graph/defs.d.ts +47 -0
  107. package/dist/lexicon/types/app/bsky/graph/follow.d.ts +8 -0
  108. package/dist/lexicon/types/app/bsky/graph/getBlocks.d.ts +34 -0
  109. package/dist/lexicon/types/app/bsky/graph/getFollowers.d.ts +36 -0
  110. package/dist/lexicon/types/app/bsky/graph/getFollows.d.ts +36 -0
  111. package/dist/lexicon/types/app/bsky/graph/getList.d.ts +36 -0
  112. package/dist/lexicon/types/app/bsky/graph/getListBlocks.d.ts +34 -0
  113. package/dist/lexicon/types/app/bsky/graph/getListMutes.d.ts +34 -0
  114. package/dist/lexicon/types/app/bsky/graph/getLists.d.ts +35 -0
  115. package/dist/lexicon/types/app/bsky/graph/getMutes.d.ts +34 -0
  116. package/dist/lexicon/types/app/bsky/graph/getSuggestedFollowsByActor.d.ts +32 -0
  117. package/dist/lexicon/types/app/bsky/graph/list.d.ts +19 -0
  118. package/dist/lexicon/types/app/bsky/graph/listblock.d.ts +8 -0
  119. package/dist/lexicon/types/app/bsky/graph/listitem.d.ts +9 -0
  120. package/dist/lexicon/types/app/bsky/graph/muteActor.d.ts +25 -0
  121. package/dist/lexicon/types/app/bsky/graph/muteActorList.d.ts +25 -0
  122. package/dist/lexicon/types/app/bsky/graph/unmuteActor.d.ts +25 -0
  123. package/dist/lexicon/types/app/bsky/graph/unmuteActorList.d.ts +25 -0
  124. package/dist/lexicon/types/app/bsky/moderation/defs.d.ts +49 -0
  125. package/dist/lexicon/types/app/bsky/moderation/getService.d.ts +29 -0
  126. package/dist/lexicon/types/app/bsky/moderation/getServices.d.ts +32 -0
  127. package/dist/lexicon/types/app/bsky/moderation/service.d.ts +17 -0
  128. package/dist/lexicon/types/app/bsky/notification/getUnreadCount.d.ts +31 -0
  129. package/dist/lexicon/types/app/bsky/notification/listNotifications.d.ts +52 -0
  130. package/dist/lexicon/types/app/bsky/notification/registerPush.d.ts +28 -0
  131. package/dist/lexicon/types/app/bsky/notification/updateSeen.d.ts +25 -0
  132. package/dist/lexicon/types/app/bsky/richtext/facet.d.ts +36 -0
  133. package/dist/lexicon/types/app/bsky/unspecced/defs.d.ts +13 -0
  134. package/dist/lexicon/types/app/bsky/unspecced/getPopular.d.ts +35 -0
  135. package/dist/lexicon/types/app/bsky/unspecced/getPopularFeedGenerators.d.ts +35 -0
  136. package/dist/lexicon/types/app/bsky/unspecced/getTimelineSkeleton.d.ts +35 -0
  137. package/dist/lexicon/types/app/bsky/unspecced/searchActorsSkeleton.d.ts +38 -0
  138. package/dist/lexicon/types/app/bsky/unspecced/searchPostsSkeleton.d.ts +37 -0
  139. package/dist/lexicon/types/com/atproto/admin/defs.d.ts +319 -0
  140. package/dist/lexicon/types/com/atproto/admin/deleteAccount.d.ts +25 -0
  141. package/dist/lexicon/types/com/atproto/admin/disableAccountInvites.d.ts +26 -0
  142. package/dist/lexicon/types/com/atproto/admin/disableInviteCodes.d.ts +26 -0
  143. package/dist/lexicon/types/com/atproto/admin/emitModerationEvent.d.ts +45 -0
  144. package/dist/lexicon/types/com/atproto/admin/enableAccountInvites.d.ts +26 -0
  145. package/dist/lexicon/types/com/atproto/admin/getAccountInfo.d.ts +29 -0
  146. package/dist/lexicon/types/com/atproto/admin/getAccountInfos.d.ts +32 -0
  147. package/dist/lexicon/types/com/atproto/admin/getInviteCodes.d.ts +35 -0
  148. package/dist/lexicon/types/com/atproto/admin/getModerationEvent.d.ts +29 -0
  149. package/dist/lexicon/types/com/atproto/admin/getRecord.d.ts +31 -0
  150. package/dist/lexicon/types/com/atproto/admin/getRepo.d.ts +30 -0
  151. package/dist/lexicon/types/com/atproto/admin/getSubjectStatus.d.ts +39 -0
  152. package/dist/lexicon/types/com/atproto/admin/queryModerationEvents.d.ts +39 -0
  153. package/dist/lexicon/types/com/atproto/admin/queryModerationStatuses.d.ts +48 -0
  154. package/dist/lexicon/types/com/atproto/admin/searchRepos.d.ts +36 -0
  155. package/dist/lexicon/types/com/atproto/admin/sendEmail.d.ts +40 -0
  156. package/dist/lexicon/types/com/atproto/admin/updateAccountEmail.d.ts +26 -0
  157. package/dist/lexicon/types/com/atproto/admin/updateAccountHandle.d.ts +26 -0
  158. package/dist/lexicon/types/com/atproto/admin/updateSubjectStatus.d.ts +46 -0
  159. package/dist/lexicon/types/com/atproto/identity/resolveHandle.d.ts +31 -0
  160. package/dist/lexicon/types/com/atproto/identity/updateHandle.d.ts +25 -0
  161. package/dist/lexicon/types/com/atproto/label/defs.d.ts +24 -0
  162. package/dist/lexicon/types/com/atproto/label/queryLabels.d.ts +36 -0
  163. package/dist/lexicon/types/com/atproto/label/subscribeLabels.d.ts +36 -0
  164. package/dist/lexicon/types/com/atproto/moderation/createReport.d.ts +52 -0
  165. package/dist/lexicon/types/com/atproto/moderation/defs.d.ts +8 -0
  166. package/dist/lexicon/types/com/atproto/repo/applyWrites.d.ts +53 -0
  167. package/dist/lexicon/types/com/atproto/repo/createRecord.d.ts +43 -0
  168. package/dist/lexicon/types/com/atproto/repo/deleteRecord.d.ts +30 -0
  169. package/dist/lexicon/types/com/atproto/repo/describeRepo.d.ts +35 -0
  170. package/dist/lexicon/types/com/atproto/repo/getRecord.d.ts +36 -0
  171. package/dist/lexicon/types/com/atproto/repo/listRecords.d.ts +47 -0
  172. package/dist/lexicon/types/com/atproto/repo/putRecord.d.ts +44 -0
  173. package/dist/lexicon/types/com/atproto/repo/strongRef.d.ts +8 -0
  174. package/dist/lexicon/types/com/atproto/repo/uploadBlob.d.ts +36 -0
  175. package/dist/lexicon/types/com/atproto/server/confirmEmail.d.ts +27 -0
  176. package/dist/lexicon/types/com/atproto/server/createAccount.d.ts +49 -0
  177. package/dist/lexicon/types/com/atproto/server/createAppPassword.d.ts +43 -0
  178. package/dist/lexicon/types/com/atproto/server/createInviteCode.d.ts +37 -0
  179. package/dist/lexicon/types/com/atproto/server/createInviteCodes.d.ts +46 -0
  180. package/dist/lexicon/types/com/atproto/server/createSession.d.ts +44 -0
  181. package/dist/lexicon/types/com/atproto/server/defs.d.ts +20 -0
  182. package/dist/lexicon/types/com/atproto/server/deleteAccount.d.ts +28 -0
  183. package/dist/lexicon/types/com/atproto/server/deleteSession.d.ts +19 -0
  184. package/dist/lexicon/types/com/atproto/server/describeServer.d.ts +41 -0
  185. package/dist/lexicon/types/com/atproto/server/getAccountInviteCodes.d.ts +34 -0
  186. package/dist/lexicon/types/com/atproto/server/getSession.d.ts +34 -0
  187. package/dist/lexicon/types/com/atproto/server/listAppPasswords.d.ts +39 -0
  188. package/dist/lexicon/types/com/atproto/server/refreshSession.d.ts +35 -0
  189. package/dist/lexicon/types/com/atproto/server/requestAccountDelete.d.ts +19 -0
  190. package/dist/lexicon/types/com/atproto/server/requestEmailConfirmation.d.ts +19 -0
  191. package/dist/lexicon/types/com/atproto/server/requestEmailUpdate.d.ts +30 -0
  192. package/dist/lexicon/types/com/atproto/server/requestPasswordReset.d.ts +25 -0
  193. package/dist/lexicon/types/com/atproto/server/reserveSigningKey.d.ts +36 -0
  194. package/dist/lexicon/types/com/atproto/server/resetPassword.d.ts +27 -0
  195. package/dist/lexicon/types/com/atproto/server/revokeAppPassword.d.ts +25 -0
  196. package/dist/lexicon/types/com/atproto/server/updateEmail.d.ts +27 -0
  197. package/dist/lexicon/types/com/atproto/sync/getBlob.d.ts +30 -0
  198. package/dist/lexicon/types/com/atproto/sync/getBlocks.d.ts +30 -0
  199. package/dist/lexicon/types/com/atproto/sync/getCheckout.d.ts +29 -0
  200. package/dist/lexicon/types/com/atproto/sync/getHead.d.ts +32 -0
  201. package/dist/lexicon/types/com/atproto/sync/getLatestCommit.d.ts +33 -0
  202. package/dist/lexicon/types/com/atproto/sync/getRecord.d.ts +32 -0
  203. package/dist/lexicon/types/com/atproto/sync/getRepo.d.ts +30 -0
  204. package/dist/lexicon/types/com/atproto/sync/listBlobs.d.ts +35 -0
  205. package/dist/lexicon/types/com/atproto/sync/listRepos.d.ts +42 -0
  206. package/dist/lexicon/types/com/atproto/sync/notifyOfUpdate.d.ts +25 -0
  207. package/dist/lexicon/types/com/atproto/sync/requestCrawl.d.ts +25 -0
  208. package/dist/lexicon/types/com/atproto/sync/subscribeRepos.d.ts +80 -0
  209. package/dist/lexicon/types/com/atproto/temp/fetchLabels.d.ts +33 -0
  210. package/dist/lexicon/types/com/atproto/temp/importRepo.d.ts +32 -0
  211. package/dist/lexicon/types/com/atproto/temp/pushBlob.d.ts +25 -0
  212. package/dist/lexicon/types/com/atproto/temp/requestPhoneVerification.d.ts +25 -0
  213. package/dist/lexicon/types/com/atproto/temp/transferAccount.d.ts +42 -0
  214. package/dist/lexicon/util.d.ts +2 -0
  215. package/dist/logger.d.ts +4 -0
  216. package/dist/mod-service/index.d.ts +155 -0
  217. package/dist/mod-service/status.d.ts +12 -0
  218. package/dist/mod-service/subject.d.ts +59 -0
  219. package/dist/mod-service/types.d.ts +19 -0
  220. package/dist/mod-service/views.d.ts +49 -0
  221. package/dist/sequencer/index.d.ts +2 -0
  222. package/dist/sequencer/outbox.d.ts +16 -0
  223. package/dist/sequencer/sequencer.d.ts +35 -0
  224. package/dist/services/index.d.ts +7 -0
  225. package/dist/services/moderation/index.d.ts +144 -0
  226. package/dist/services/moderation/status.d.ts +12 -0
  227. package/dist/services/moderation/subject.d.ts +60 -0
  228. package/dist/services/moderation/types.d.ts +19 -0
  229. package/dist/services/moderation/views.d.ts +42 -0
  230. package/dist/services/types.d.ts +2 -0
  231. package/dist/util/date.d.ts +1 -0
  232. package/dist/util/debug.d.ts +1 -0
  233. package/dist/util/retry.d.ts +3 -0
  234. package/dist/util.d.ts +3 -0
  235. package/jest.config.js +6 -0
  236. package/package.json +67 -0
  237. package/src/api/admin/emitModerationEvent.ts +130 -0
  238. package/src/api/admin/getModerationEvent.ts +19 -0
  239. package/src/api/admin/getRecord.ts +34 -0
  240. package/src/api/admin/getRepo.ts +31 -0
  241. package/src/api/admin/queryModerationEvents.ts +40 -0
  242. package/src/api/admin/queryModerationStatuses.ts +57 -0
  243. package/src/api/admin/searchRepos.ts +42 -0
  244. package/src/api/admin/util.ts +54 -0
  245. package/src/api/health.ts +20 -0
  246. package/src/api/index.ts +28 -0
  247. package/src/api/moderation/createReport.ts +41 -0
  248. package/src/api/moderation/util.ts +65 -0
  249. package/src/api/temp/fetchLabels.ts +29 -0
  250. package/src/api/well-known.ts +35 -0
  251. package/src/auth.ts +147 -0
  252. package/src/background.ts +35 -0
  253. package/src/config/config.ts +84 -0
  254. package/src/config/env.ts +41 -0
  255. package/src/config/index.ts +3 -0
  256. package/src/config/secrets.ts +23 -0
  257. package/src/context.ts +180 -0
  258. package/src/daemon/context.ts +90 -0
  259. package/src/daemon/event-pusher.ts +296 -0
  260. package/src/daemon/event-reverser.ts +74 -0
  261. package/src/daemon/index.ts +33 -0
  262. package/src/db/index.ts +197 -0
  263. package/src/db/migrations/20231219T205730722Z-init.ts +164 -0
  264. package/src/db/migrations/index.ts +5 -0
  265. package/src/db/migrations/provider.ts +25 -0
  266. package/src/db/pagination.ts +216 -0
  267. package/src/db/schema/blob_push_event.ts +21 -0
  268. package/src/db/schema/index.ts +18 -0
  269. package/src/db/schema/label.ts +12 -0
  270. package/src/db/schema/moderation_event.ts +35 -0
  271. package/src/db/schema/moderation_subject_status.ts +32 -0
  272. package/src/db/schema/record_push_event.ts +21 -0
  273. package/src/db/schema/repo_push_event.ts +19 -0
  274. package/src/db/types.ts +15 -0
  275. package/src/error.ts +12 -0
  276. package/src/index.ts +102 -0
  277. package/src/lexicon/index.ts +1626 -0
  278. package/src/lexicon/lexicons.ts +8050 -0
  279. package/src/lexicon/types/app/bsky/actor/defs.ts +235 -0
  280. package/src/lexicon/types/app/bsky/actor/getPreferences.ts +44 -0
  281. package/src/lexicon/types/app/bsky/actor/getProfile.ts +41 -0
  282. package/src/lexicon/types/app/bsky/actor/getProfiles.ts +46 -0
  283. package/src/lexicon/types/app/bsky/actor/getSuggestions.ts +48 -0
  284. package/src/lexicon/types/app/bsky/actor/profile.ts +32 -0
  285. package/src/lexicon/types/app/bsky/actor/putPreferences.ts +39 -0
  286. package/src/lexicon/types/app/bsky/actor/searchActors.ts +52 -0
  287. package/src/lexicon/types/app/bsky/actor/searchActorsTypeahead.ts +50 -0
  288. package/src/lexicon/types/app/bsky/embed/external.ts +82 -0
  289. package/src/lexicon/types/app/bsky/embed/images.ts +96 -0
  290. package/src/lexicon/types/app/bsky/embed/record.ts +120 -0
  291. package/src/lexicon/types/app/bsky/embed/recordWithMedia.ts +53 -0
  292. package/src/lexicon/types/app/bsky/feed/defs.ts +308 -0
  293. package/src/lexicon/types/app/bsky/feed/describeFeedGenerator.ts +80 -0
  294. package/src/lexicon/types/app/bsky/feed/generator.ts +35 -0
  295. package/src/lexicon/types/app/bsky/feed/getActorFeeds.ts +49 -0
  296. package/src/lexicon/types/app/bsky/feed/getActorLikes.ts +50 -0
  297. package/src/lexicon/types/app/bsky/feed/getAuthorFeed.ts +56 -0
  298. package/src/lexicon/types/app/bsky/feed/getFeed.ts +50 -0
  299. package/src/lexicon/types/app/bsky/feed/getFeedGenerator.ts +48 -0
  300. package/src/lexicon/types/app/bsky/feed/getFeedGenerators.ts +46 -0
  301. package/src/lexicon/types/app/bsky/feed/getFeedSkeleton.ts +50 -0
  302. package/src/lexicon/types/app/bsky/feed/getLikes.ts +69 -0
  303. package/src/lexicon/types/app/bsky/feed/getListFeed.ts +50 -0
  304. package/src/lexicon/types/app/bsky/feed/getPostThread.ts +53 -0
  305. package/src/lexicon/types/app/bsky/feed/getPosts.ts +46 -0
  306. package/src/lexicon/types/app/bsky/feed/getRepostedBy.ts +52 -0
  307. package/src/lexicon/types/app/bsky/feed/getSuggestedFeeds.ts +48 -0
  308. package/src/lexicon/types/app/bsky/feed/getTimeline.ts +49 -0
  309. package/src/lexicon/types/app/bsky/feed/like.ts +26 -0
  310. package/src/lexicon/types/app/bsky/feed/post.ts +102 -0
  311. package/src/lexicon/types/app/bsky/feed/repost.ts +27 -0
  312. package/src/lexicon/types/app/bsky/feed/searchPosts.ts +54 -0
  313. package/src/lexicon/types/app/bsky/feed/threadgate.ts +84 -0
  314. package/src/lexicon/types/app/bsky/graph/block.ts +26 -0
  315. package/src/lexicon/types/app/bsky/graph/defs.ts +104 -0
  316. package/src/lexicon/types/app/bsky/graph/follow.ts +26 -0
  317. package/src/lexicon/types/app/bsky/graph/getBlocks.ts +48 -0
  318. package/src/lexicon/types/app/bsky/graph/getFollowers.ts +50 -0
  319. package/src/lexicon/types/app/bsky/graph/getFollows.ts +50 -0
  320. package/src/lexicon/types/app/bsky/graph/getList.ts +50 -0
  321. package/src/lexicon/types/app/bsky/graph/getListBlocks.ts +48 -0
  322. package/src/lexicon/types/app/bsky/graph/getListMutes.ts +48 -0
  323. package/src/lexicon/types/app/bsky/graph/getLists.ts +49 -0
  324. package/src/lexicon/types/app/bsky/graph/getMutes.ts +48 -0
  325. package/src/lexicon/types/app/bsky/graph/getSuggestedFollowsByActor.ts +46 -0
  326. package/src/lexicon/types/app/bsky/graph/list.ts +36 -0
  327. package/src/lexicon/types/app/bsky/graph/listblock.ts +26 -0
  328. package/src/lexicon/types/app/bsky/graph/listitem.ts +27 -0
  329. package/src/lexicon/types/app/bsky/graph/muteActor.ts +38 -0
  330. package/src/lexicon/types/app/bsky/graph/muteActorList.ts +38 -0
  331. package/src/lexicon/types/app/bsky/graph/unmuteActor.ts +38 -0
  332. package/src/lexicon/types/app/bsky/graph/unmuteActorList.ts +38 -0
  333. package/src/lexicon/types/app/bsky/notification/getUnreadCount.ts +45 -0
  334. package/src/lexicon/types/app/bsky/notification/listNotifications.ts +87 -0
  335. package/src/lexicon/types/app/bsky/notification/registerPush.ts +41 -0
  336. package/src/lexicon/types/app/bsky/notification/updateSeen.ts +38 -0
  337. package/src/lexicon/types/app/bsky/richtext/facet.ts +97 -0
  338. package/src/lexicon/types/app/bsky/unspecced/defs.ts +41 -0
  339. package/src/lexicon/types/app/bsky/unspecced/getPopularFeedGenerators.ts +49 -0
  340. package/src/lexicon/types/app/bsky/unspecced/getTimelineSkeleton.ts +49 -0
  341. package/src/lexicon/types/app/bsky/unspecced/searchActorsSkeleton.ts +56 -0
  342. package/src/lexicon/types/app/bsky/unspecced/searchPostsSkeleton.ts +54 -0
  343. package/src/lexicon/types/com/atproto/admin/defs.ts +719 -0
  344. package/src/lexicon/types/com/atproto/admin/deleteAccount.ts +38 -0
  345. package/src/lexicon/types/com/atproto/admin/disableAccountInvites.ts +40 -0
  346. package/src/lexicon/types/com/atproto/admin/disableInviteCodes.ts +39 -0
  347. package/src/lexicon/types/com/atproto/admin/emitModerationEvent.ts +66 -0
  348. package/src/lexicon/types/com/atproto/admin/enableAccountInvites.ts +40 -0
  349. package/src/lexicon/types/com/atproto/admin/getAccountInfo.ts +41 -0
  350. package/src/lexicon/types/com/atproto/admin/getAccountInfos.ts +46 -0
  351. package/src/lexicon/types/com/atproto/admin/getInviteCodes.ts +49 -0
  352. package/src/lexicon/types/com/atproto/admin/getModerationEvent.ts +41 -0
  353. package/src/lexicon/types/com/atproto/admin/getRecord.ts +43 -0
  354. package/src/lexicon/types/com/atproto/admin/getRepo.ts +42 -0
  355. package/src/lexicon/types/com/atproto/admin/getSubjectStatus.ts +54 -0
  356. package/src/lexicon/types/com/atproto/admin/queryModerationEvents.ts +56 -0
  357. package/src/lexicon/types/com/atproto/admin/queryModerationStatuses.ts +72 -0
  358. package/src/lexicon/types/com/atproto/admin/searchRepos.ts +51 -0
  359. package/src/lexicon/types/com/atproto/admin/sendEmail.ts +54 -0
  360. package/src/lexicon/types/com/atproto/admin/updateAccountEmail.ts +40 -0
  361. package/src/lexicon/types/com/atproto/admin/updateAccountHandle.ts +39 -0
  362. package/src/lexicon/types/com/atproto/admin/updateSubjectStatus.ts +61 -0
  363. package/src/lexicon/types/com/atproto/identity/resolveHandle.ts +46 -0
  364. package/src/lexicon/types/com/atproto/identity/updateHandle.ts +38 -0
  365. package/src/lexicon/types/com/atproto/label/defs.ts +73 -0
  366. package/src/lexicon/types/com/atproto/label/queryLabels.ts +52 -0
  367. package/src/lexicon/types/com/atproto/label/subscribeLabels.ts +67 -0
  368. package/src/lexicon/types/com/atproto/moderation/createReport.ts +65 -0
  369. package/src/lexicon/types/com/atproto/moderation/defs.ts +32 -0
  370. package/src/lexicon/types/com/atproto/repo/applyWrites.ts +103 -0
  371. package/src/lexicon/types/com/atproto/repo/createRecord.ts +62 -0
  372. package/src/lexicon/types/com/atproto/repo/deleteRecord.ts +48 -0
  373. package/src/lexicon/types/com/atproto/repo/describeRepo.ts +50 -0
  374. package/src/lexicon/types/com/atproto/repo/getRecord.ts +54 -0
  375. package/src/lexicon/types/com/atproto/repo/listRecords.ts +77 -0
  376. package/src/lexicon/types/com/atproto/repo/putRecord.ts +64 -0
  377. package/src/lexicon/types/com/atproto/repo/strongRef.ts +26 -0
  378. package/src/lexicon/types/com/atproto/repo/uploadBlob.ts +47 -0
  379. package/src/lexicon/types/com/atproto/server/confirmEmail.ts +40 -0
  380. package/src/lexicon/types/com/atproto/server/createAccount.ts +69 -0
  381. package/src/lexicon/types/com/atproto/server/createAppPassword.ts +69 -0
  382. package/src/lexicon/types/com/atproto/server/createInviteCode.ts +50 -0
  383. package/src/lexicon/types/com/atproto/server/createInviteCodes.ts +72 -0
  384. package/src/lexicon/types/com/atproto/server/createSession.ts +58 -0
  385. package/src/lexicon/types/com/atproto/server/defs.ts +48 -0
  386. package/src/lexicon/types/com/atproto/server/deleteAccount.ts +41 -0
  387. package/src/lexicon/types/com/atproto/server/deleteSession.ts +31 -0
  388. package/src/lexicon/types/com/atproto/server/describeServer.ts +64 -0
  389. package/src/lexicon/types/com/atproto/server/getAccountInviteCodes.ts +48 -0
  390. package/src/lexicon/types/com/atproto/server/getSession.ts +47 -0
  391. package/src/lexicon/types/com/atproto/server/listAppPasswords.ts +62 -0
  392. package/src/lexicon/types/com/atproto/server/refreshSession.ts +48 -0
  393. package/src/lexicon/types/com/atproto/server/requestAccountDelete.ts +31 -0
  394. package/src/lexicon/types/com/atproto/server/requestEmailConfirmation.ts +31 -0
  395. package/src/lexicon/types/com/atproto/server/requestEmailUpdate.ts +43 -0
  396. package/src/lexicon/types/com/atproto/server/requestPasswordReset.ts +38 -0
  397. package/src/lexicon/types/com/atproto/server/reserveSigningKey.ts +51 -0
  398. package/src/lexicon/types/com/atproto/server/resetPassword.ts +40 -0
  399. package/src/lexicon/types/com/atproto/server/revokeAppPassword.ts +38 -0
  400. package/src/lexicon/types/com/atproto/server/updateEmail.ts +41 -0
  401. package/src/lexicon/types/com/atproto/sync/getBlob.ts +43 -0
  402. package/src/lexicon/types/com/atproto/sync/getBlocks.ts +42 -0
  403. package/src/lexicon/types/com/atproto/sync/getCheckout.ts +41 -0
  404. package/src/lexicon/types/com/atproto/sync/getHead.ts +47 -0
  405. package/src/lexicon/types/com/atproto/sync/getLatestCommit.ts +48 -0
  406. package/src/lexicon/types/com/atproto/sync/getRecord.ts +45 -0
  407. package/src/lexicon/types/com/atproto/sync/getRepo.ts +43 -0
  408. package/src/lexicon/types/com/atproto/sync/listBlobs.ts +51 -0
  409. package/src/lexicon/types/com/atproto/sync/listRepos.ts +66 -0
  410. package/src/lexicon/types/com/atproto/sync/notifyOfUpdate.ts +39 -0
  411. package/src/lexicon/types/com/atproto/sync/requestCrawl.ts +39 -0
  412. package/src/lexicon/types/com/atproto/sync/subscribeRepos.ts +161 -0
  413. package/src/lexicon/types/com/atproto/temp/fetchLabels.ts +47 -0
  414. package/src/lexicon/types/com/atproto/temp/importRepo.ts +45 -0
  415. package/src/lexicon/types/com/atproto/temp/pushBlob.ts +39 -0
  416. package/src/lexicon/types/com/atproto/temp/requestPhoneVerification.ts +38 -0
  417. package/src/lexicon/types/com/atproto/temp/transferAccount.ts +62 -0
  418. package/src/lexicon/util.ts +13 -0
  419. package/src/logger.ts +19 -0
  420. package/src/mod-service/index.ts +758 -0
  421. package/src/mod-service/status.ts +264 -0
  422. package/src/mod-service/subject.ts +136 -0
  423. package/src/mod-service/types.ts +32 -0
  424. package/src/mod-service/views.ts +531 -0
  425. package/src/util.ts +26 -0
  426. package/test.env +2 -0
  427. package/test.log +0 -0
  428. package/tests/__snapshots__/get-record.test.ts.snap +173 -0
  429. package/tests/__snapshots__/get-repo.test.ts.snap +57 -0
  430. package/tests/__snapshots__/moderation-events.test.ts.snap +168 -0
  431. package/tests/__snapshots__/moderation-statuses.test.ts.snap +64 -0
  432. package/tests/__snapshots__/moderation.test.ts.snap +55 -0
  433. package/tests/_util.ts +192 -0
  434. package/tests/db.test.ts +184 -0
  435. package/tests/get-record.test.ts +110 -0
  436. package/tests/get-repo.test.ts +131 -0
  437. package/tests/moderation-appeals.test.ts +269 -0
  438. package/tests/moderation-events.test.ts +220 -0
  439. package/tests/moderation-statuses.test.ts +144 -0
  440. package/tests/moderation.test.ts +961 -0
  441. package/tests/repo-search.test.ts +123 -0
  442. package/tests/server.test.ts +76 -0
  443. package/tsconfig.build.json +4 -0
  444. package/tsconfig.json +21 -0
@@ -0,0 +1,269 @@
1
+ import { TestNetwork, SeedClient, basicSeed } from '@atproto/dev-env'
2
+ import AtpAgent, {
3
+ ComAtprotoAdminDefs,
4
+ ComAtprotoAdminEmitModerationEvent,
5
+ ComAtprotoAdminQueryModerationStatuses,
6
+ } from '@atproto/api'
7
+ import {
8
+ REASONMISLEADING,
9
+ REASONSPAM,
10
+ } from '../src/lexicon/types/com/atproto/moderation/defs'
11
+ import {
12
+ REVIEWCLOSED,
13
+ REVIEWOPEN,
14
+ } from '@atproto/api/src/client/types/com/atproto/admin/defs'
15
+ import { REASONAPPEAL } from '@atproto/api/src/client/types/com/atproto/moderation/defs'
16
+ import { REVIEWESCALATED } from '../src/lexicon/types/com/atproto/admin/defs'
17
+
18
+ describe('moderation-appeals', () => {
19
+ let network: TestNetwork
20
+ let agent: AtpAgent
21
+ let pdsAgent: AtpAgent
22
+ let sc: SeedClient
23
+
24
+ const emitModerationEvent = async (
25
+ eventData: ComAtprotoAdminEmitModerationEvent.InputSchema,
26
+ ) => {
27
+ return pdsAgent.api.com.atproto.admin.emitModerationEvent(eventData, {
28
+ encoding: 'application/json',
29
+ headers: network.ozone.adminAuthHeaders('moderator'),
30
+ })
31
+ }
32
+
33
+ const queryModerationStatuses = (
34
+ statusQuery: ComAtprotoAdminQueryModerationStatuses.QueryParams,
35
+ ) =>
36
+ agent.api.com.atproto.admin.queryModerationStatuses(statusQuery, {
37
+ headers: network.ozone.adminAuthHeaders('moderator'),
38
+ })
39
+
40
+ beforeAll(async () => {
41
+ network = await TestNetwork.create({
42
+ dbPostgresSchema: 'ozone_moderation_statuses',
43
+ })
44
+ agent = network.ozone.getClient()
45
+ pdsAgent = network.pds.getClient()
46
+ sc = network.getSeedClient()
47
+ await basicSeed(sc)
48
+ await network.processAll()
49
+ })
50
+
51
+ afterAll(async () => {
52
+ await network.close()
53
+ })
54
+
55
+ const assertSubjectStatus = async (
56
+ subject: string,
57
+ status: string,
58
+ appealed: boolean | undefined,
59
+ ): Promise<ComAtprotoAdminDefs.SubjectStatusView | undefined> => {
60
+ const { data } = await queryModerationStatuses({
61
+ subject,
62
+ })
63
+ expect(data.subjectStatuses[0]?.reviewState).toEqual(status)
64
+ expect(data.subjectStatuses[0]?.appealed).toEqual(appealed)
65
+ return data.subjectStatuses[0]
66
+ }
67
+
68
+ describe('appeals from users', () => {
69
+ const getBobsPostSubject = () => ({
70
+ $type: 'com.atproto.repo.strongRef',
71
+ uri: sc.posts[sc.dids.bob][1].ref.uriStr,
72
+ cid: sc.posts[sc.dids.bob][1].ref.cidStr,
73
+ })
74
+ const getCarolPostSubject = () => ({
75
+ $type: 'com.atproto.repo.strongRef',
76
+ uri: sc.posts[sc.dids.carol][0].ref.uriStr,
77
+ cid: sc.posts[sc.dids.carol][0].ref.cidStr,
78
+ })
79
+ const assertBobsPostStatus = async (
80
+ status: string,
81
+ appealed: boolean | undefined,
82
+ ) => assertSubjectStatus(getBobsPostSubject().uri, status, appealed)
83
+
84
+ it('only changes subject status if original author of the content or a moderator is appealing', async () => {
85
+ // Create a report by alice
86
+ await emitModerationEvent({
87
+ event: {
88
+ $type: 'com.atproto.admin.defs#modEventReport',
89
+ reportType: REASONMISLEADING,
90
+ },
91
+ subject: getBobsPostSubject(),
92
+ createdBy: sc.dids.alice,
93
+ })
94
+
95
+ await assertBobsPostStatus(REVIEWOPEN, undefined)
96
+
97
+ // Create a report as normal user with appeal type
98
+ expect(
99
+ sc.createReport({
100
+ reportedBy: sc.dids.carol,
101
+ reasonType: REASONAPPEAL,
102
+ reason: 'appealing',
103
+ subject: getBobsPostSubject(),
104
+ }),
105
+ ).rejects.toThrow('You cannot appeal this report')
106
+
107
+ // Verify that the appeal status did not change
108
+ await assertBobsPostStatus(REVIEWOPEN, undefined)
109
+
110
+ // Emit report event as moderator
111
+ await emitModerationEvent({
112
+ event: {
113
+ $type: 'com.atproto.admin.defs#modEventReport',
114
+ reportType: REASONAPPEAL,
115
+ },
116
+ subject: getBobsPostSubject(),
117
+ createdBy: sc.dids.alice,
118
+ })
119
+
120
+ // Verify that appeal status changed when appeal report was emitted by moderator
121
+ const status = await assertBobsPostStatus(REVIEWOPEN, true)
122
+ expect(status?.appealedAt).not.toBeNull()
123
+
124
+ // Create a report as normal user for carol's post
125
+ await sc.createReport({
126
+ reportedBy: sc.dids.alice,
127
+ reasonType: REASONMISLEADING,
128
+ reason: 'lies!',
129
+ subject: getCarolPostSubject(),
130
+ })
131
+
132
+ // Verify that the appeal status on carol's post is undefined
133
+ await assertSubjectStatus(
134
+ getCarolPostSubject().uri,
135
+ REVIEWOPEN,
136
+ undefined,
137
+ )
138
+
139
+ await sc.createReport({
140
+ reportedBy: sc.dids.carol,
141
+ reasonType: REASONAPPEAL,
142
+ reason: 'appealing',
143
+ subject: getCarolPostSubject(),
144
+ })
145
+ // Verify that the appeal status on carol's post is true
146
+ await assertSubjectStatus(getCarolPostSubject().uri, REVIEWOPEN, true)
147
+ })
148
+ it('allows multiple appeals and updates last appealed timestamp', async () => {
149
+ // Resolve appeal with acknowledge
150
+ await emitModerationEvent({
151
+ event: {
152
+ $type: 'com.atproto.admin.defs#modEventResolveAppeal',
153
+ },
154
+ subject: getBobsPostSubject(),
155
+ createdBy: sc.dids.carol,
156
+ })
157
+
158
+ const previousStatus = await assertBobsPostStatus(REVIEWOPEN, false)
159
+
160
+ await emitModerationEvent({
161
+ event: {
162
+ $type: 'com.atproto.admin.defs#modEventReport',
163
+ reportType: REASONAPPEAL,
164
+ },
165
+ subject: getBobsPostSubject(),
166
+ createdBy: sc.dids.bob,
167
+ })
168
+
169
+ // Verify that even after the appeal event by bob for his post, the appeal status is true again with new timestamp
170
+ const newStatus = await assertBobsPostStatus(REVIEWOPEN, true)
171
+ expect(
172
+ new Date(`${previousStatus?.lastAppealedAt}`).getTime(),
173
+ ).toBeLessThan(new Date(`${newStatus?.lastAppealedAt}`).getTime())
174
+ })
175
+ })
176
+
177
+ describe('appeal resolution', () => {
178
+ const getAlicesPostSubject = () => ({
179
+ $type: 'com.atproto.repo.strongRef',
180
+ uri: sc.posts[sc.dids.alice][1].ref.uriStr,
181
+ cid: sc.posts[sc.dids.alice][1].ref.cidStr,
182
+ })
183
+ it('appeal status is maintained while review state changes based on incoming events', async () => {
184
+ // Bob reports alice's post
185
+ await emitModerationEvent({
186
+ event: {
187
+ $type: 'com.atproto.admin.defs#modEventReport',
188
+ reportType: REASONMISLEADING,
189
+ },
190
+ subject: getAlicesPostSubject(),
191
+ createdBy: sc.dids.bob,
192
+ })
193
+
194
+ // Moderator acknowledges the report, assume a label was applied too
195
+ await emitModerationEvent({
196
+ event: {
197
+ $type: 'com.atproto.admin.defs#modEventAcknowledge',
198
+ },
199
+ subject: getAlicesPostSubject(),
200
+ createdBy: sc.dids.carol,
201
+ })
202
+
203
+ // Alice appeals the report
204
+ await emitModerationEvent({
205
+ event: {
206
+ $type: 'com.atproto.admin.defs#modEventReport',
207
+ reportType: REASONAPPEAL,
208
+ },
209
+ subject: getAlicesPostSubject(),
210
+ createdBy: sc.dids.alice,
211
+ })
212
+
213
+ await assertSubjectStatus(getAlicesPostSubject().uri, REVIEWOPEN, true)
214
+
215
+ // Bob reports it again
216
+ await emitModerationEvent({
217
+ event: {
218
+ $type: 'com.atproto.admin.defs#modEventReport',
219
+ reportType: REASONSPAM,
220
+ },
221
+ subject: getAlicesPostSubject(),
222
+ createdBy: sc.dids.bob,
223
+ })
224
+
225
+ // Assert that the status is still REVIEWOPEN, as report events are meant to do
226
+ await assertSubjectStatus(getAlicesPostSubject().uri, REVIEWOPEN, true)
227
+
228
+ // Emit an escalation event
229
+ await emitModerationEvent({
230
+ event: {
231
+ $type: 'com.atproto.admin.defs#modEventEscalate',
232
+ },
233
+ subject: getAlicesPostSubject(),
234
+ createdBy: sc.dids.carol,
235
+ })
236
+
237
+ await assertSubjectStatus(
238
+ getAlicesPostSubject().uri,
239
+ REVIEWESCALATED,
240
+ true,
241
+ )
242
+
243
+ // Emit an acknowledge event
244
+ await emitModerationEvent({
245
+ event: {
246
+ $type: 'com.atproto.admin.defs#modEventAcknowledge',
247
+ },
248
+ subject: getAlicesPostSubject(),
249
+ createdBy: sc.dids.carol,
250
+ })
251
+
252
+ // Assert that status moved on to reviewClosed while appealed status is still true
253
+ await assertSubjectStatus(getAlicesPostSubject().uri, REVIEWCLOSED, true)
254
+
255
+ // Emit a resolveAppeal event
256
+ await emitModerationEvent({
257
+ event: {
258
+ $type: 'com.atproto.admin.defs#modEventResolveAppeal',
259
+ comment: 'lgtm',
260
+ },
261
+ subject: getAlicesPostSubject(),
262
+ createdBy: sc.dids.carol,
263
+ })
264
+
265
+ // Assert that status stayed the same while appealed status is still true
266
+ await assertSubjectStatus(getAlicesPostSubject().uri, REVIEWCLOSED, false)
267
+ })
268
+ })
269
+ })
@@ -0,0 +1,220 @@
1
+ import { TestNetwork, SeedClient, basicSeed } from '@atproto/dev-env'
2
+ import AtpAgent, { ComAtprotoAdminDefs } from '@atproto/api'
3
+ import { forSnapshot } from './_util'
4
+ import {
5
+ REASONMISLEADING,
6
+ REASONSPAM,
7
+ } from '../src/lexicon/types/com/atproto/moderation/defs'
8
+
9
+ describe('moderation-events', () => {
10
+ let network: TestNetwork
11
+ let agent: AtpAgent
12
+ let pdsAgent: AtpAgent
13
+ let sc: SeedClient
14
+
15
+ const emitModerationEvent = async (eventData) => {
16
+ return pdsAgent.api.com.atproto.admin.emitModerationEvent(eventData, {
17
+ encoding: 'application/json',
18
+ headers: network.bsky.adminAuthHeaders('moderator'),
19
+ })
20
+ }
21
+
22
+ const queryModerationEvents = (eventQuery) =>
23
+ agent.api.com.atproto.admin.queryModerationEvents(eventQuery, {
24
+ headers: network.bsky.adminAuthHeaders('moderator'),
25
+ })
26
+
27
+ const seedEvents = async () => {
28
+ const bobsAccount = {
29
+ $type: 'com.atproto.admin.defs#repoRef',
30
+ did: sc.dids.bob,
31
+ }
32
+ const alicesAccount = {
33
+ $type: 'com.atproto.admin.defs#repoRef',
34
+ did: sc.dids.alice,
35
+ }
36
+ const bobsPost = {
37
+ $type: 'com.atproto.repo.strongRef',
38
+ uri: sc.posts[sc.dids.bob][0].ref.uriStr,
39
+ cid: sc.posts[sc.dids.bob][0].ref.cidStr,
40
+ }
41
+ const alicesPost = {
42
+ $type: 'com.atproto.repo.strongRef',
43
+ uri: sc.posts[sc.dids.alice][0].ref.uriStr,
44
+ cid: sc.posts[sc.dids.alice][0].ref.cidStr,
45
+ }
46
+
47
+ for (let i = 0; i < 4; i++) {
48
+ await emitModerationEvent({
49
+ event: {
50
+ $type: 'com.atproto.admin.defs#modEventReport',
51
+ reportType: i % 2 ? REASONSPAM : REASONMISLEADING,
52
+ comment: 'X',
53
+ },
54
+ // Report bob's account by alice and vice versa
55
+ subject: i % 2 ? bobsAccount : alicesAccount,
56
+ createdBy: i % 2 ? sc.dids.alice : sc.dids.bob,
57
+ })
58
+ await emitModerationEvent({
59
+ event: {
60
+ $type: 'com.atproto.admin.defs#modEventReport',
61
+ reportType: REASONSPAM,
62
+ comment: 'X',
63
+ },
64
+ // Report bob's post by alice and vice versa
65
+ subject: i % 2 ? bobsPost : alicesPost,
66
+ createdBy: i % 2 ? sc.dids.alice : sc.dids.bob,
67
+ })
68
+ }
69
+ }
70
+
71
+ beforeAll(async () => {
72
+ network = await TestNetwork.create({
73
+ dbPostgresSchema: 'ozone_moderation_events',
74
+ })
75
+ agent = network.ozone.getClient()
76
+ pdsAgent = network.pds.getClient()
77
+ sc = network.getSeedClient()
78
+ await basicSeed(sc)
79
+ await network.processAll()
80
+ await seedEvents()
81
+ })
82
+
83
+ afterAll(async () => {
84
+ await network.close()
85
+ })
86
+
87
+ describe('query events', () => {
88
+ it('returns all events for record or repo', async () => {
89
+ const [bobsEvents, alicesPostEvents] = await Promise.all([
90
+ queryModerationEvents({
91
+ subject: sc.dids.bob,
92
+ }),
93
+ queryModerationEvents({
94
+ subject: sc.posts[sc.dids.alice][0].ref.uriStr,
95
+ }),
96
+ ])
97
+
98
+ expect(forSnapshot(bobsEvents.data.events)).toMatchSnapshot()
99
+ expect(forSnapshot(alicesPostEvents.data.events)).toMatchSnapshot()
100
+ })
101
+
102
+ it('filters events by types', async () => {
103
+ const alicesAccount = {
104
+ $type: 'com.atproto.admin.defs#repoRef',
105
+ did: sc.dids.alice,
106
+ }
107
+ await Promise.all([
108
+ emitModerationEvent({
109
+ event: {
110
+ $type: 'com.atproto.admin.defs#modEventComment',
111
+ comment: 'X',
112
+ },
113
+ subject: alicesAccount,
114
+ createdBy: 'did:plc:moderator',
115
+ }),
116
+ emitModerationEvent({
117
+ event: {
118
+ $type: 'com.atproto.admin.defs#modEventEscalate',
119
+ comment: 'X',
120
+ },
121
+ subject: alicesAccount,
122
+ createdBy: 'did:plc:moderator',
123
+ }),
124
+ ])
125
+ const [allEvents, reportEvents] = await Promise.all([
126
+ queryModerationEvents({
127
+ subject: sc.dids.alice,
128
+ }),
129
+ queryModerationEvents({
130
+ subject: sc.dids.alice,
131
+ types: ['com.atproto.admin.defs#modEventReport'],
132
+ }),
133
+ ])
134
+
135
+ expect(allEvents.data.events.length).toBeGreaterThan(
136
+ reportEvents.data.events.length,
137
+ )
138
+ expect(
139
+ [...new Set(reportEvents.data.events.map((e) => e.event.$type))].length,
140
+ ).toEqual(1)
141
+
142
+ expect(
143
+ [...new Set(allEvents.data.events.map((e) => e.event.$type))].length,
144
+ ).toEqual(3)
145
+ })
146
+
147
+ it('returns events for all content by user', async () => {
148
+ const [forAccount, forPost] = await Promise.all([
149
+ queryModerationEvents({
150
+ subject: sc.dids.bob,
151
+ includeAllUserRecords: true,
152
+ }),
153
+ queryModerationEvents({
154
+ subject: sc.posts[sc.dids.bob][0].ref.uriStr,
155
+ includeAllUserRecords: true,
156
+ }),
157
+ ])
158
+
159
+ expect(forAccount.data.events.length).toEqual(forPost.data.events.length)
160
+ // Save events are returned from both requests
161
+ expect(forPost.data.events.map(({ id }) => id).sort()).toEqual(
162
+ forAccount.data.events.map(({ id }) => id).sort(),
163
+ )
164
+ })
165
+
166
+ it('returns paginated list of events with cursor', async () => {
167
+ const allEvents = await queryModerationEvents({
168
+ subject: sc.dids.bob,
169
+ includeAllUserRecords: true,
170
+ })
171
+
172
+ const getPaginatedEvents = async (
173
+ sortDirection: 'asc' | 'desc' = 'desc',
174
+ ) => {
175
+ let defaultCursor: undefined | string = undefined
176
+ const events: ComAtprotoAdminDefs.ModEventView[] = []
177
+ let count = 0
178
+ do {
179
+ // get 1 event at a time and check we get all events
180
+ const { data } = await queryModerationEvents({
181
+ limit: 1,
182
+ subject: sc.dids.bob,
183
+ includeAllUserRecords: true,
184
+ cursor: defaultCursor,
185
+ sortDirection,
186
+ })
187
+ events.push(...data.events)
188
+ defaultCursor = data.cursor
189
+ count++
190
+ // The count is a circuit breaker to prevent infinite loop in case of failing test
191
+ } while (defaultCursor && count < 10)
192
+
193
+ return events
194
+ }
195
+
196
+ const defaultEvents = await getPaginatedEvents()
197
+ const reversedEvents = await getPaginatedEvents('asc')
198
+
199
+ expect(allEvents.data.events.length).toEqual(5)
200
+ expect(defaultEvents.length).toEqual(allEvents.data.events.length)
201
+ expect(reversedEvents.length).toEqual(allEvents.data.events.length)
202
+ expect(reversedEvents[0].id).toEqual(defaultEvents[4].id)
203
+ })
204
+ })
205
+
206
+ describe('get event', () => {
207
+ it('gets an event by specific id', async () => {
208
+ const { data } = await pdsAgent.api.com.atproto.admin.getModerationEvent(
209
+ {
210
+ id: 1,
211
+ },
212
+ {
213
+ headers: network.bsky.adminAuthHeaders('moderator'),
214
+ },
215
+ )
216
+
217
+ expect(forSnapshot(data)).toMatchSnapshot()
218
+ })
219
+ })
220
+ })
@@ -0,0 +1,144 @@
1
+ import { TestNetwork, SeedClient, basicSeed } from '@atproto/dev-env'
2
+ import AtpAgent, {
3
+ ComAtprotoAdminDefs,
4
+ ComAtprotoAdminQueryModerationStatuses,
5
+ } from '@atproto/api'
6
+ import { forSnapshot } from './_util'
7
+ import {
8
+ REASONMISLEADING,
9
+ REASONSPAM,
10
+ } from '../src/lexicon/types/com/atproto/moderation/defs'
11
+
12
+ describe('moderation-statuses', () => {
13
+ let network: TestNetwork
14
+ let agent: AtpAgent
15
+ let pdsAgent: AtpAgent
16
+ let sc: SeedClient
17
+
18
+ const emitModerationEvent = async (eventData) => {
19
+ return pdsAgent.api.com.atproto.admin.emitModerationEvent(eventData, {
20
+ encoding: 'application/json',
21
+ headers: network.bsky.adminAuthHeaders('moderator'),
22
+ })
23
+ }
24
+
25
+ const queryModerationStatuses = (statusQuery) =>
26
+ agent.api.com.atproto.admin.queryModerationStatuses(statusQuery, {
27
+ headers: network.bsky.adminAuthHeaders('moderator'),
28
+ })
29
+
30
+ const seedEvents = async () => {
31
+ const bobsAccount = {
32
+ $type: 'com.atproto.admin.defs#repoRef',
33
+ did: sc.dids.bob,
34
+ }
35
+ const carlasAccount = {
36
+ $type: 'com.atproto.admin.defs#repoRef',
37
+ did: sc.dids.alice,
38
+ }
39
+ const bobsPost = {
40
+ $type: 'com.atproto.repo.strongRef',
41
+ uri: sc.posts[sc.dids.bob][1].ref.uriStr,
42
+ cid: sc.posts[sc.dids.bob][1].ref.cidStr,
43
+ }
44
+ const alicesPost = {
45
+ $type: 'com.atproto.repo.strongRef',
46
+ uri: sc.posts[sc.dids.alice][1].ref.uriStr,
47
+ cid: sc.posts[sc.dids.alice][1].ref.cidStr,
48
+ }
49
+
50
+ for (let i = 0; i < 4; i++) {
51
+ await emitModerationEvent({
52
+ event: {
53
+ $type: 'com.atproto.admin.defs#modEventReport',
54
+ reportType: i % 2 ? REASONSPAM : REASONMISLEADING,
55
+ comment: 'X',
56
+ },
57
+ // Report bob's account by alice and vice versa
58
+ subject: i % 2 ? bobsAccount : carlasAccount,
59
+ createdBy: i % 2 ? sc.dids.alice : sc.dids.bob,
60
+ })
61
+ await emitModerationEvent({
62
+ event: {
63
+ $type: 'com.atproto.admin.defs#modEventReport',
64
+ reportType: REASONSPAM,
65
+ comment: 'X',
66
+ },
67
+ // Report bob's post by alice and vice versa
68
+ subject: i % 2 ? bobsPost : alicesPost,
69
+ createdBy: i % 2 ? sc.dids.alice : sc.dids.bob,
70
+ })
71
+ }
72
+ }
73
+
74
+ beforeAll(async () => {
75
+ network = await TestNetwork.create({
76
+ dbPostgresSchema: 'ozone_moderation_statuses',
77
+ })
78
+ agent = network.ozone.getClient()
79
+ pdsAgent = network.pds.getClient()
80
+ sc = network.getSeedClient()
81
+ await basicSeed(sc)
82
+ await network.processAll()
83
+ await seedEvents()
84
+ })
85
+
86
+ afterAll(async () => {
87
+ await network.close()
88
+ })
89
+
90
+ describe('query statuses', () => {
91
+ it('returns statuses for subjects that received moderation events', async () => {
92
+ const response = await queryModerationStatuses({})
93
+
94
+ expect(forSnapshot(response.data.subjectStatuses)).toMatchSnapshot()
95
+ })
96
+
97
+ it('returns paginated statuses', async () => {
98
+ // We know there will be exactly 4 statuses in db
99
+ const getPaginatedStatuses = async (
100
+ params: ComAtprotoAdminQueryModerationStatuses.QueryParams,
101
+ ) => {
102
+ let cursor: string | undefined = ''
103
+ const statuses: ComAtprotoAdminDefs.SubjectStatusView[] = []
104
+ let count = 0
105
+ do {
106
+ const results = await queryModerationStatuses({
107
+ limit: 1,
108
+ cursor,
109
+ ...params,
110
+ })
111
+ cursor = results.data.cursor
112
+ statuses.push(...results.data.subjectStatuses)
113
+ count++
114
+ // The count is just a brake-check to prevent infinite loop
115
+ } while (cursor && count < 10)
116
+
117
+ return statuses
118
+ }
119
+
120
+ const list = await getPaginatedStatuses({})
121
+ expect(list[0].id).toEqual(4)
122
+ expect(list[list.length - 1].id).toEqual(1)
123
+
124
+ await emitModerationEvent({
125
+ subject: list[1].subject,
126
+ event: {
127
+ $type: 'com.atproto.admin.defs#modEventAcknowledge',
128
+ comment: 'X',
129
+ },
130
+ createdBy: sc.dids.bob,
131
+ })
132
+
133
+ const listReviewedFirst = await getPaginatedStatuses({
134
+ sortDirection: 'desc',
135
+ sortField: 'lastReviewedAt',
136
+ })
137
+
138
+ // Verify that the item that was recently reviewed comes up first when sorted descendingly
139
+ // while the result set always contains same number of items regardless of sorting
140
+ expect(listReviewedFirst[0].id).toEqual(list[1].id)
141
+ expect(listReviewedFirst.length).toEqual(list.length)
142
+ })
143
+ })
144
+ })