@atproto/bsky 0.0.75 → 0.0.77

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 (268) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/api/app/bsky/actor/getProfiles.d.ts.map +1 -1
  3. package/dist/api/app/bsky/actor/getProfiles.js +9 -1
  4. package/dist/api/app/bsky/actor/getProfiles.js.map +1 -1
  5. package/dist/api/app/bsky/actor/searchActorsTypeahead.js +10 -2
  6. package/dist/api/app/bsky/actor/searchActorsTypeahead.js.map +1 -1
  7. package/dist/api/app/bsky/feed/getActorLikes.js +2 -2
  8. package/dist/api/app/bsky/feed/getActorLikes.js.map +1 -1
  9. package/dist/api/app/bsky/feed/getFeed.d.ts.map +1 -1
  10. package/dist/api/app/bsky/feed/getFeed.js +8 -1
  11. package/dist/api/app/bsky/feed/getFeed.js.map +1 -1
  12. package/dist/api/app/bsky/feed/getLikes.js +6 -6
  13. package/dist/api/app/bsky/feed/getLikes.js.map +1 -1
  14. package/dist/api/app/bsky/feed/getPosts.d.ts.map +1 -1
  15. package/dist/api/app/bsky/feed/getPosts.js +12 -5
  16. package/dist/api/app/bsky/feed/getPosts.js.map +1 -1
  17. package/dist/api/app/bsky/feed/getQuotes.d.ts +4 -0
  18. package/dist/api/app/bsky/feed/getQuotes.d.ts.map +1 -0
  19. package/dist/api/app/bsky/feed/getQuotes.js +67 -0
  20. package/dist/api/app/bsky/feed/getQuotes.js.map +1 -0
  21. package/dist/api/app/bsky/feed/getRepostedBy.js +6 -6
  22. package/dist/api/app/bsky/feed/getRepostedBy.js.map +1 -1
  23. package/dist/api/app/bsky/feed/searchPosts.js +4 -4
  24. package/dist/api/app/bsky/feed/searchPosts.js.map +1 -1
  25. package/dist/api/app/bsky/graph/getFollowers.js +8 -8
  26. package/dist/api/app/bsky/graph/getFollowers.js.map +1 -1
  27. package/dist/api/app/bsky/graph/getList.d.ts.map +1 -1
  28. package/dist/api/app/bsky/graph/getList.js +32 -2
  29. package/dist/api/app/bsky/graph/getList.js.map +1 -1
  30. package/dist/api/app/bsky/notification/listNotifications.d.ts.map +1 -1
  31. package/dist/api/app/bsky/notification/listNotifications.js +29 -8
  32. package/dist/api/app/bsky/notification/listNotifications.js.map +1 -1
  33. package/dist/api/index.d.ts.map +1 -1
  34. package/dist/api/index.js +2 -0
  35. package/dist/api/index.js.map +1 -1
  36. package/dist/auth-verifier.d.ts +8 -3
  37. package/dist/auth-verifier.d.ts.map +1 -1
  38. package/dist/auth-verifier.js +43 -29
  39. package/dist/auth-verifier.js.map +1 -1
  40. package/dist/data-plane/server/db/database-schema.d.ts +4 -2
  41. package/dist/data-plane/server/db/database-schema.d.ts.map +1 -1
  42. package/dist/data-plane/server/db/migrations/20240723T220700077Z-quotes-post-aggs.d.ts +4 -0
  43. package/dist/data-plane/server/db/migrations/20240723T220700077Z-quotes-post-aggs.d.ts.map +1 -0
  44. package/dist/data-plane/server/db/migrations/20240723T220700077Z-quotes-post-aggs.js +15 -0
  45. package/dist/data-plane/server/db/migrations/20240723T220700077Z-quotes-post-aggs.js.map +1 -0
  46. package/dist/data-plane/server/db/migrations/20240723T220703655Z-quotes.d.ts +4 -0
  47. package/dist/data-plane/server/db/migrations/20240723T220703655Z-quotes.d.ts.map +1 -0
  48. package/dist/data-plane/server/db/migrations/20240723T220703655Z-quotes.js +30 -0
  49. package/dist/data-plane/server/db/migrations/20240723T220703655Z-quotes.js.map +1 -0
  50. package/dist/data-plane/server/db/migrations/20240801T193939827Z-post-gate.d.ts +4 -0
  51. package/dist/data-plane/server/db/migrations/20240801T193939827Z-post-gate.d.ts.map +1 -0
  52. package/dist/data-plane/server/db/migrations/20240801T193939827Z-post-gate.js +20 -0
  53. package/dist/data-plane/server/db/migrations/20240801T193939827Z-post-gate.js.map +1 -0
  54. package/dist/data-plane/server/db/migrations/20240808T224251220Z-post-gate-flags.d.ts +4 -0
  55. package/dist/data-plane/server/db/migrations/20240808T224251220Z-post-gate-flags.d.ts.map +1 -0
  56. package/dist/data-plane/server/db/migrations/20240808T224251220Z-post-gate-flags.js +28 -0
  57. package/dist/data-plane/server/db/migrations/20240808T224251220Z-post-gate-flags.js.map +1 -0
  58. package/dist/data-plane/server/db/migrations/index.d.ts +4 -0
  59. package/dist/data-plane/server/db/migrations/index.d.ts.map +1 -1
  60. package/dist/data-plane/server/db/migrations/index.js +5 -1
  61. package/dist/data-plane/server/db/migrations/index.js.map +1 -1
  62. package/dist/data-plane/server/db/tables/post-agg.d.ts +1 -0
  63. package/dist/data-plane/server/db/tables/post-agg.d.ts.map +1 -1
  64. package/dist/data-plane/server/db/tables/post-gate.d.ts +14 -0
  65. package/dist/data-plane/server/db/tables/post-gate.d.ts.map +1 -0
  66. package/dist/data-plane/server/db/tables/post-gate.js +4 -0
  67. package/dist/data-plane/server/db/tables/post-gate.js.map +1 -0
  68. package/dist/data-plane/server/db/tables/post.d.ts +3 -0
  69. package/dist/data-plane/server/db/tables/post.d.ts.map +1 -1
  70. package/dist/data-plane/server/db/tables/quote.d.ts +16 -0
  71. package/dist/data-plane/server/db/tables/quote.d.ts.map +1 -0
  72. package/dist/data-plane/server/db/tables/quote.js +4 -0
  73. package/dist/data-plane/server/db/tables/quote.js.map +1 -0
  74. package/dist/data-plane/server/indexing/index.d.ts +2 -0
  75. package/dist/data-plane/server/indexing/index.d.ts.map +1 -1
  76. package/dist/data-plane/server/indexing/index.js +6 -0
  77. package/dist/data-plane/server/indexing/index.js.map +1 -1
  78. package/dist/data-plane/server/indexing/plugins/post-gate.d.ts +10 -0
  79. package/dist/data-plane/server/indexing/plugins/post-gate.d.ts.map +1 -0
  80. package/dist/data-plane/server/indexing/plugins/post-gate.js +101 -0
  81. package/dist/data-plane/server/indexing/plugins/post-gate.js.map +1 -0
  82. package/dist/data-plane/server/indexing/plugins/post.d.ts +2 -0
  83. package/dist/data-plane/server/indexing/plugins/post.d.ts.map +1 -1
  84. package/dist/data-plane/server/indexing/plugins/post.js +122 -15
  85. package/dist/data-plane/server/indexing/plugins/post.js.map +1 -1
  86. package/dist/data-plane/server/indexing/plugins/thread-gate.d.ts.map +1 -1
  87. package/dist/data-plane/server/indexing/plugins/thread-gate.js +12 -0
  88. package/dist/data-plane/server/indexing/plugins/thread-gate.js.map +1 -1
  89. package/dist/data-plane/server/routes/index.d.ts.map +1 -1
  90. package/dist/data-plane/server/routes/index.js +2 -0
  91. package/dist/data-plane/server/routes/index.js.map +1 -1
  92. package/dist/data-plane/server/routes/interactions.d.ts.map +1 -1
  93. package/dist/data-plane/server/routes/interactions.js +2 -1
  94. package/dist/data-plane/server/routes/interactions.js.map +1 -1
  95. package/dist/data-plane/server/routes/quotes.d.ts +6 -0
  96. package/dist/data-plane/server/routes/quotes.d.ts.map +1 -0
  97. package/dist/data-plane/server/routes/quotes.js +27 -0
  98. package/dist/data-plane/server/routes/quotes.js.map +1 -0
  99. package/dist/data-plane/server/routes/records.d.ts.map +1 -1
  100. package/dist/data-plane/server/routes/records.js +11 -1
  101. package/dist/data-plane/server/routes/records.js.map +1 -1
  102. package/dist/data-plane/server/util.d.ts +6 -7
  103. package/dist/data-plane/server/util.d.ts.map +1 -1
  104. package/dist/data-plane/server/util.js +1 -9
  105. package/dist/data-plane/server/util.js.map +1 -1
  106. package/dist/hydration/feed.d.ts +10 -0
  107. package/dist/hydration/feed.d.ts.map +1 -1
  108. package/dist/hydration/feed.js +31 -7
  109. package/dist/hydration/feed.js.map +1 -1
  110. package/dist/hydration/hydrator.d.ts +5 -2
  111. package/dist/hydration/hydrator.d.ts.map +1 -1
  112. package/dist/hydration/hydrator.js +102 -38
  113. package/dist/hydration/hydrator.js.map +1 -1
  114. package/dist/hydration/util.d.ts +0 -1
  115. package/dist/hydration/util.d.ts.map +1 -1
  116. package/dist/hydration/util.js +1 -5
  117. package/dist/hydration/util.js.map +1 -1
  118. package/dist/lexicon/index.d.ts +2 -0
  119. package/dist/lexicon/index.d.ts.map +1 -1
  120. package/dist/lexicon/index.js +4 -0
  121. package/dist/lexicon/index.js.map +1 -1
  122. package/dist/lexicon/lexicons.d.ts +141 -0
  123. package/dist/lexicon/lexicons.d.ts.map +1 -1
  124. package/dist/lexicon/lexicons.js +142 -0
  125. package/dist/lexicon/lexicons.js.map +1 -1
  126. package/dist/lexicon/types/app/bsky/embed/record.d.ts +8 -1
  127. package/dist/lexicon/types/app/bsky/embed/record.d.ts.map +1 -1
  128. package/dist/lexicon/types/app/bsky/embed/record.js +11 -1
  129. package/dist/lexicon/types/app/bsky/embed/record.js.map +1 -1
  130. package/dist/lexicon/types/app/bsky/feed/defs.d.ts +2 -0
  131. package/dist/lexicon/types/app/bsky/feed/defs.d.ts.map +1 -1
  132. package/dist/lexicon/types/app/bsky/feed/defs.js.map +1 -1
  133. package/dist/lexicon/types/app/bsky/feed/getQuotes.d.ts +44 -0
  134. package/dist/lexicon/types/app/bsky/feed/getQuotes.d.ts.map +1 -0
  135. package/dist/lexicon/types/app/bsky/feed/getQuotes.js +3 -0
  136. package/dist/lexicon/types/app/bsky/feed/getQuotes.js.map +1 -0
  137. package/dist/lexicon/types/app/bsky/feed/postgate.d.ts +25 -0
  138. package/dist/lexicon/types/app/bsky/feed/postgate.d.ts.map +1 -0
  139. package/dist/lexicon/types/app/bsky/feed/postgate.js +27 -0
  140. package/dist/lexicon/types/app/bsky/feed/postgate.js.map +1 -0
  141. package/dist/lexicon/types/app/bsky/feed/threadgate.d.ts +2 -0
  142. package/dist/lexicon/types/app/bsky/feed/threadgate.d.ts.map +1 -1
  143. package/dist/lexicon/types/app/bsky/feed/threadgate.js.map +1 -1
  144. package/dist/proto/bsky_connect.d.ts +21 -1
  145. package/dist/proto/bsky_connect.d.ts.map +1 -1
  146. package/dist/proto/bsky_connect.js +20 -0
  147. package/dist/proto/bsky_connect.js.map +1 -1
  148. package/dist/proto/bsky_pb.d.ts +96 -0
  149. package/dist/proto/bsky_pb.d.ts.map +1 -1
  150. package/dist/proto/bsky_pb.js +306 -4
  151. package/dist/proto/bsky_pb.js.map +1 -1
  152. package/dist/util/uris.d.ts +12 -0
  153. package/dist/util/uris.d.ts.map +1 -0
  154. package/dist/util/uris.js +34 -0
  155. package/dist/util/uris.js.map +1 -0
  156. package/dist/views/index.d.ts +8 -2
  157. package/dist/views/index.d.ts.map +1 -1
  158. package/dist/views/index.js +83 -39
  159. package/dist/views/index.js.map +1 -1
  160. package/dist/views/types.d.ts +1 -1
  161. package/dist/views/types.d.ts.map +1 -1
  162. package/dist/views/types.js.map +1 -1
  163. package/dist/views/util.d.ts +11 -1
  164. package/dist/views/util.d.ts.map +1 -1
  165. package/dist/views/util.js +19 -8
  166. package/dist/views/util.js.map +1 -1
  167. package/package.json +6 -6
  168. package/proto/bsky.proto +33 -0
  169. package/src/api/app/bsky/actor/getProfiles.ts +10 -1
  170. package/src/api/app/bsky/actor/searchActorsTypeahead.ts +9 -4
  171. package/src/api/app/bsky/feed/getActorLikes.ts +1 -1
  172. package/src/api/app/bsky/feed/getFeed.ts +12 -1
  173. package/src/api/app/bsky/feed/getLikes.ts +1 -1
  174. package/src/api/app/bsky/feed/getPosts.ts +10 -2
  175. package/src/api/app/bsky/feed/getQuotes.ts +105 -0
  176. package/src/api/app/bsky/feed/getRepostedBy.ts +1 -1
  177. package/src/api/app/bsky/feed/searchPosts.ts +1 -1
  178. package/src/api/app/bsky/graph/getFollowers.ts +1 -1
  179. package/src/api/app/bsky/graph/getList.ts +47 -4
  180. package/src/api/app/bsky/notification/listNotifications.ts +32 -6
  181. package/src/api/index.ts +2 -0
  182. package/src/auth-verifier.ts +78 -51
  183. package/src/data-plane/server/db/database-schema.ts +7 -3
  184. package/src/data-plane/server/db/migrations/20240723T220700077Z-quotes-post-aggs.ts +12 -0
  185. package/src/data-plane/server/db/migrations/20240723T220703655Z-quotes.ts +28 -0
  186. package/src/data-plane/server/db/migrations/20240801T193939827Z-post-gate.ts +17 -0
  187. package/src/data-plane/server/db/migrations/20240808T224251220Z-post-gate-flags.ts +25 -0
  188. package/src/data-plane/server/db/migrations/index.ts +4 -0
  189. package/src/data-plane/server/db/tables/post-agg.ts +1 -0
  190. package/src/data-plane/server/db/tables/post-gate.ts +12 -0
  191. package/src/data-plane/server/db/tables/post.ts +3 -0
  192. package/src/data-plane/server/db/tables/quote.ts +15 -0
  193. package/src/data-plane/server/indexing/index.ts +7 -0
  194. package/src/data-plane/server/indexing/plugins/post-gate.ts +104 -0
  195. package/src/data-plane/server/indexing/plugins/post.ts +151 -16
  196. package/src/data-plane/server/indexing/plugins/thread-gate.ts +12 -0
  197. package/src/data-plane/server/routes/index.ts +2 -0
  198. package/src/data-plane/server/routes/interactions.ts +2 -1
  199. package/src/data-plane/server/routes/quotes.ts +32 -0
  200. package/src/data-plane/server/routes/records.ts +11 -1
  201. package/src/data-plane/server/util.ts +0 -8
  202. package/src/hydration/feed.ts +58 -12
  203. package/src/hydration/hydrator.ts +112 -24
  204. package/src/hydration/util.ts +0 -4
  205. package/src/lexicon/index.ts +12 -0
  206. package/src/lexicon/lexicons.ts +145 -0
  207. package/src/lexicon/types/app/bsky/embed/record.ts +19 -0
  208. package/src/lexicon/types/app/bsky/feed/defs.ts +2 -0
  209. package/src/lexicon/types/app/bsky/feed/getQuotes.ts +54 -0
  210. package/src/lexicon/types/app/bsky/feed/postgate.ts +47 -0
  211. package/src/lexicon/types/app/bsky/feed/threadgate.ts +2 -0
  212. package/src/proto/bsky_connect.ts +24 -0
  213. package/src/proto/bsky_pb.ts +289 -0
  214. package/src/util/uris.ts +31 -0
  215. package/src/views/index.ts +90 -35
  216. package/src/views/types.ts +1 -0
  217. package/src/views/util.ts +37 -7
  218. package/tests/__snapshots__/feed-generation.test.ts.snap +37 -0
  219. package/tests/admin/admin-auth.test.ts +15 -8
  220. package/tests/auth.test.ts +2 -1
  221. package/tests/data-plane/__snapshots__/indexing.test.ts.snap +18 -0
  222. package/tests/data-plane/handle-invalidation.test.ts +31 -5
  223. package/tests/data-plane/indexing.test.ts +139 -23
  224. package/tests/data-plane/thread-mutes.test.ts +41 -9
  225. package/tests/feed-generation.test.ts +150 -32
  226. package/tests/postgates.test.ts +186 -0
  227. package/tests/seed/feed-hidden-replies.ts +62 -0
  228. package/tests/seed/postgates.ts +56 -0
  229. package/tests/server.test.ts +1 -1
  230. package/tests/views/__snapshots__/author-feed.test.ts.snap +56 -0
  231. package/tests/views/__snapshots__/block-lists.test.ts.snap +6 -0
  232. package/tests/views/__snapshots__/blocks.test.ts.snap +10 -0
  233. package/tests/views/__snapshots__/list-feed.test.ts.snap +22 -0
  234. package/tests/views/__snapshots__/lists.test.ts.snap +145 -26
  235. package/tests/views/__snapshots__/mute-lists.test.ts.snap +8 -0
  236. package/tests/views/__snapshots__/mutes.test.ts.snap +6 -0
  237. package/tests/views/__snapshots__/posts.test.ts.snap +12 -0
  238. package/tests/views/__snapshots__/quotes.test.ts.snap +399 -0
  239. package/tests/views/__snapshots__/starter-packs.test.ts.snap +245 -4
  240. package/tests/views/__snapshots__/thread.test.ts.snap +50 -0
  241. package/tests/views/__snapshots__/timeline.test.ts.snap +170 -0
  242. package/tests/views/account-deactivation.test.ts +8 -2
  243. package/tests/views/actor-likes.test.ts +27 -6
  244. package/tests/views/actor-search.test.ts +5 -1
  245. package/tests/views/author-feed.test.ts +76 -21
  246. package/tests/views/block-lists.test.ts +201 -40
  247. package/tests/views/blocks.test.ts +245 -46
  248. package/tests/views/feed-hidden-replies.test.ts +246 -0
  249. package/tests/views/feed-view-post.test.ts +501 -0
  250. package/tests/views/follows.test.ts +133 -22
  251. package/tests/views/known-followers.test.ts +43 -7
  252. package/tests/views/labeler-service.test.ts +36 -6
  253. package/tests/views/likes.test.ts +8 -5
  254. package/tests/views/list-feed.test.ts +25 -4
  255. package/tests/views/lists.test.ts +73 -31
  256. package/tests/views/mute-lists.test.ts +101 -29
  257. package/tests/views/mutes.test.ts +77 -17
  258. package/tests/views/notifications.test.ts +141 -25
  259. package/tests/views/posts.test.ts +13 -2
  260. package/tests/views/profile.test.ts +37 -11
  261. package/tests/views/quotes.test.ts +105 -0
  262. package/tests/views/reposts.test.ts +31 -5
  263. package/tests/views/starter-packs.test.ts +83 -3
  264. package/tests/views/suggested-follows.test.ts +31 -5
  265. package/tests/views/suggestions.test.ts +37 -6
  266. package/tests/views/thread.test.ts +121 -20
  267. package/tests/views/threadgating.test.ts +128 -22
  268. package/tests/views/timeline.test.ts +67 -14
@@ -1,5 +1,6 @@
1
1
  import { RecordRef, SeedClient, TestNetwork, usersSeed } from '@atproto/dev-env'
2
2
  import { AtpAgent } from '@atproto/api'
3
+ import { ids } from '../../src/lexicon/lexicons'
3
4
 
4
5
  describe('thread mutes', () => {
5
6
  let network: TestNetwork
@@ -35,7 +36,10 @@ describe('thread mutes', () => {
35
36
  { root: rootPost.uriStr },
36
37
  {
37
38
  encoding: 'application/json',
38
- headers: await network.serviceHeaders(alice),
39
+ headers: await network.serviceHeaders(
40
+ alice,
41
+ ids.AppBskyGraphMuteThread,
42
+ ),
39
43
  },
40
44
  )
41
45
  })
@@ -46,7 +50,7 @@ describe('thread mutes', () => {
46
50
  uris: [rootPost.uriStr, replyPost.uriStr],
47
51
  },
48
52
  {
49
- headers: await network.serviceHeaders(alice),
53
+ headers: await network.serviceHeaders(alice, ids.AppBskyFeedGetPosts),
50
54
  },
51
55
  )
52
56
  expect(res.data.posts[0].viewer?.threadMuted).toBe(true)
@@ -60,7 +64,12 @@ describe('thread mutes', () => {
60
64
 
61
65
  const notifsRes = await agent.api.app.bsky.notification.listNotifications(
62
66
  {},
63
- { headers: await network.serviceHeaders(alice) },
67
+ {
68
+ headers: await network.serviceHeaders(
69
+ alice,
70
+ ids.AppBskyNotificationListNotifications,
71
+ ),
72
+ },
64
73
  )
65
74
  expect(notifsRes.data.notifications.length).toBe(0)
66
75
  })
@@ -72,7 +81,12 @@ describe('thread mutes', () => {
72
81
 
73
82
  const notifsRes = await agent.api.app.bsky.notification.listNotifications(
74
83
  {},
75
- { headers: await network.serviceHeaders(alice) },
84
+ {
85
+ headers: await network.serviceHeaders(
86
+ alice,
87
+ ids.AppBskyNotificationListNotifications,
88
+ ),
89
+ },
76
90
  )
77
91
  expect(notifsRes.data.notifications.length).toBe(0)
78
92
  })
@@ -84,7 +98,12 @@ describe('thread mutes', () => {
84
98
 
85
99
  const notifsRes = await agent.api.app.bsky.notification.listNotifications(
86
100
  {},
87
- { headers: await network.serviceHeaders(alice) },
101
+ {
102
+ headers: await network.serviceHeaders(
103
+ alice,
104
+ ids.AppBskyNotificationListNotifications,
105
+ ),
106
+ },
88
107
  )
89
108
  expect(notifsRes.data.notifications.length).toBe(0)
90
109
  })
@@ -96,7 +115,12 @@ describe('thread mutes', () => {
96
115
 
97
116
  const notifsRes = await agent.api.app.bsky.notification.listNotifications(
98
117
  {},
99
- { headers: await network.serviceHeaders(alice) },
118
+ {
119
+ headers: await network.serviceHeaders(
120
+ alice,
121
+ ids.AppBskyNotificationListNotifications,
122
+ ),
123
+ },
100
124
  )
101
125
  expect(notifsRes.data.notifications.length).toBe(0)
102
126
  })
@@ -106,7 +130,10 @@ describe('thread mutes', () => {
106
130
  { root: rootPost.uriStr },
107
131
  {
108
132
  encoding: 'application/json',
109
- headers: await network.serviceHeaders(alice),
133
+ headers: await network.serviceHeaders(
134
+ alice,
135
+ ids.AppBskyGraphUnmuteThread,
136
+ ),
110
137
  },
111
138
  )
112
139
  })
@@ -117,7 +144,7 @@ describe('thread mutes', () => {
117
144
  uris: [rootPost.uriStr, replyPost.uriStr],
118
145
  },
119
146
  {
120
- headers: await network.serviceHeaders(alice),
147
+ headers: await network.serviceHeaders(alice, ids.AppBskyFeedGetPosts),
121
148
  },
122
149
  )
123
150
  expect(res.data.posts[0].viewer?.threadMuted).toBe(false)
@@ -133,7 +160,12 @@ describe('thread mutes', () => {
133
160
 
134
161
  const notifsRes = await agent.api.app.bsky.notification.listNotifications(
135
162
  {},
136
- { headers: await network.serviceHeaders(alice) },
163
+ {
164
+ headers: await network.serviceHeaders(
165
+ alice,
166
+ ids.AppBskyNotificationListNotifications,
167
+ ),
168
+ },
137
169
  )
138
170
  expect(notifsRes.data.notifications.length).toBe(4)
139
171
  })
@@ -191,7 +191,12 @@ describe('feed generation', () => {
191
191
  const paginator = async (cursor?: string) => {
192
192
  const res = await agent.api.app.bsky.feed.getActorFeeds(
193
193
  { actor: alice, cursor, limit: 2 },
194
- { headers: await network.serviceHeaders(sc.dids.bob) },
194
+ {
195
+ headers: await network.serviceHeaders(
196
+ sc.dids.bob,
197
+ ids.AppBskyFeedGetActorFeeds,
198
+ ),
199
+ },
195
200
  )
196
201
  return res.data
197
202
  }
@@ -224,7 +229,12 @@ describe('feed generation', () => {
224
229
  await network.processAll()
225
230
  const view = await agent.api.app.bsky.feed.getPosts(
226
231
  { uris: [res.uri] },
227
- { headers: await network.serviceHeaders(sc.dids.bob) },
232
+ {
233
+ headers: await network.serviceHeaders(
234
+ sc.dids.bob,
235
+ ids.AppBskyFeedGetPosts,
236
+ ),
237
+ },
228
238
  )
229
239
  expect(view.data.posts.length).toBe(1)
230
240
  expect(forSnapshot(view.data.posts[0])).toMatchSnapshot()
@@ -246,7 +256,12 @@ describe('feed generation', () => {
246
256
  await network.processAll()
247
257
  const view = await agent.api.app.bsky.feed.getPosts(
248
258
  { uris: [res.uri] },
249
- { headers: await network.serviceHeaders(sc.dids.bob) },
259
+ {
260
+ headers: await network.serviceHeaders(
261
+ sc.dids.bob,
262
+ ids.AppBskyFeedGetPosts,
263
+ ),
264
+ },
250
265
  )
251
266
  expect(view.data.posts.length).toBe(1)
252
267
  expect(forSnapshot(view.data.posts[0])).toMatchSnapshot()
@@ -300,7 +315,12 @@ describe('feed generation', () => {
300
315
  await network.processAll()
301
316
  const view = await agent.api.app.bsky.feed.getPosts(
302
317
  { uris: [res.uri] },
303
- { headers: await network.serviceHeaders(sc.dids.bob) },
318
+ {
319
+ headers: await network.serviceHeaders(
320
+ sc.dids.bob,
321
+ ids.AppBskyFeedGetPosts,
322
+ ),
323
+ },
304
324
  )
305
325
  expect(view.data.posts.length).toBe(1)
306
326
  expect(forSnapshot(view.data.posts[0])).toMatchSnapshot()
@@ -325,7 +345,12 @@ describe('feed generation', () => {
325
345
  await network.processAll()
326
346
  const view = await agent.api.app.bsky.feed.getPosts(
327
347
  { uris: [res.uri] },
328
- { headers: await network.serviceHeaders(sc.dids.bob) },
348
+ {
349
+ headers: await network.serviceHeaders(
350
+ sc.dids.bob,
351
+ ids.AppBskyFeedGetPosts,
352
+ ),
353
+ },
329
354
  )
330
355
  expect(view.data.posts.length).toBe(1)
331
356
  expect(forSnapshot(view.data.posts[0])).toMatchSnapshot()
@@ -335,7 +360,12 @@ describe('feed generation', () => {
335
360
  it('describes a feed gen & returns online status', async () => {
336
361
  const resEven = await agent.api.app.bsky.feed.getFeedGenerator(
337
362
  { feed: feedUriAll },
338
- { headers: await network.serviceHeaders(sc.dids.bob) },
363
+ {
364
+ headers: await network.serviceHeaders(
365
+ sc.dids.bob,
366
+ ids.AppBskyFeedGetFeedGenerator,
367
+ ),
368
+ },
339
369
  )
340
370
  expect(forSnapshot(resEven.data)).toMatchSnapshot()
341
371
  expect(resEven.data.isOnline).toBe(true)
@@ -345,7 +375,12 @@ describe('feed generation', () => {
345
375
  it('does not describe taken-down feed', async () => {
346
376
  const tryGetFeed = agent.api.app.bsky.feed.getFeedGenerator(
347
377
  { feed: feedUriPrime },
348
- { headers: await network.serviceHeaders(sc.dids.bob) },
378
+ {
379
+ headers: await network.serviceHeaders(
380
+ sc.dids.bob,
381
+ ids.AppBskyFeedGetFeedGenerator,
382
+ ),
383
+ },
349
384
  )
350
385
  await expect(tryGetFeed).rejects.toThrow('could not find feed')
351
386
  })
@@ -354,7 +389,12 @@ describe('feed generation', () => {
354
389
  it.skip('handles an unsupported algo', async () => {
355
390
  const resOdd = await agent.api.app.bsky.feed.getFeedGenerator(
356
391
  { feed: feedUriOdd },
357
- { headers: await network.serviceHeaders(sc.dids.bob) },
392
+ {
393
+ headers: await network.serviceHeaders(
394
+ sc.dids.bob,
395
+ ids.AppBskyFeedGetFeedGenerator,
396
+ ),
397
+ },
358
398
  )
359
399
  expect(resOdd.data.isOnline).toBe(true)
360
400
  expect(resOdd.data.isValid).toBe(false)
@@ -391,7 +431,12 @@ describe('feed generation', () => {
391
431
  {
392
432
  feed: allUriBob.toString(),
393
433
  },
394
- { headers: await network.serviceHeaders(sc.dids.alice) },
434
+ {
435
+ headers: await network.serviceHeaders(
436
+ sc.dids.alice,
437
+ ids.AppBskyFeedGetFeedGenerator,
438
+ ),
439
+ },
395
440
  )
396
441
  expect(res.data.isOnline).toBe(false)
397
442
  expect(res.data.isValid).toBe(false)
@@ -402,7 +447,12 @@ describe('feed generation', () => {
402
447
  it('describes multiple feed gens', async () => {
403
448
  const resEven = await agent.api.app.bsky.feed.getFeedGenerators(
404
449
  { feeds: [feedUriEven, feedUriAll, feedUriPrime] },
405
- { headers: await network.serviceHeaders(sc.dids.bob) },
450
+ {
451
+ headers: await network.serviceHeaders(
452
+ sc.dids.bob,
453
+ ids.AppBskyFeedGetFeedGenerators,
454
+ ),
455
+ },
406
456
  )
407
457
  expect(forSnapshot(resEven.data)).toMatchSnapshot()
408
458
  expect(resEven.data.feeds.map((fg) => fg.uri)).not.toContain(feedUriPrime) // taken-down
@@ -413,7 +463,12 @@ describe('feed generation', () => {
413
463
  it('returns list of suggested feed generators', async () => {
414
464
  const resEven = await agent.api.app.bsky.feed.getSuggestedFeeds(
415
465
  {},
416
- { headers: await network.serviceHeaders(sc.dids.bob) },
466
+ {
467
+ headers: await network.serviceHeaders(
468
+ sc.dids.bob,
469
+ ids.AppBskyFeedGetSuggestedFeeds,
470
+ ),
471
+ },
417
472
  )
418
473
  expect(forSnapshot(resEven.data)).toMatchSnapshot()
419
474
  expect(resEven.data.feeds.map((fg) => fg.uri)).not.toContain(feedUriPrime) // taken-down
@@ -424,7 +479,12 @@ describe('feed generation', () => {
424
479
  it('gets popular feed generators', async () => {
425
480
  const res = await agent.api.app.bsky.unspecced.getPopularFeedGenerators(
426
481
  {},
427
- { headers: await network.serviceHeaders(sc.dids.bob) },
482
+ {
483
+ headers: await network.serviceHeaders(
484
+ sc.dids.bob,
485
+ ids.AppBskyUnspeccedGetPopularFeedGenerators,
486
+ ),
487
+ },
428
488
  )
429
489
  expect(res.data.feeds.map((f) => f.uri)).not.toContain(feedUriPrime) // taken-down
430
490
  expect(res.data.feeds.map((f) => f.uri)).toEqual([
@@ -437,7 +497,12 @@ describe('feed generation', () => {
437
497
  it('searches feed generators', async () => {
438
498
  const res = await agent.api.app.bsky.unspecced.getPopularFeedGenerators(
439
499
  { query: 'all' },
440
- { headers: await network.serviceHeaders(sc.dids.bob) },
500
+ {
501
+ headers: await network.serviceHeaders(
502
+ sc.dids.bob,
503
+ ids.AppBskyUnspeccedGetPopularFeedGenerators,
504
+ ),
505
+ },
441
506
  )
442
507
  expect(res.data.feeds.map((f) => f.uri)).toEqual([feedUriAll])
443
508
  })
@@ -446,17 +511,32 @@ describe('feed generation', () => {
446
511
  const resFull =
447
512
  await agent.api.app.bsky.unspecced.getPopularFeedGenerators(
448
513
  {},
449
- { headers: await network.serviceHeaders(sc.dids.bob) },
514
+ {
515
+ headers: await network.serviceHeaders(
516
+ sc.dids.bob,
517
+ ids.AppBskyUnspeccedGetPopularFeedGenerators,
518
+ ),
519
+ },
450
520
  )
451
521
  const resOne =
452
522
  await agent.api.app.bsky.unspecced.getPopularFeedGenerators(
453
523
  { limit: 2 },
454
- { headers: await network.serviceHeaders(sc.dids.bob) },
524
+ {
525
+ headers: await network.serviceHeaders(
526
+ sc.dids.bob,
527
+ ids.AppBskyUnspeccedGetPopularFeedGenerators,
528
+ ),
529
+ },
455
530
  )
456
531
  const resTwo =
457
532
  await agent.api.app.bsky.unspecced.getPopularFeedGenerators(
458
533
  { cursor: resOne.data.cursor },
459
- { headers: await network.serviceHeaders(sc.dids.bob) },
534
+ {
535
+ headers: await network.serviceHeaders(
536
+ sc.dids.bob,
537
+ ids.AppBskyUnspeccedGetPopularFeedGenerators,
538
+ ),
539
+ },
460
540
  )
461
541
  expect([...resOne.data.feeds, ...resTwo.data.feeds]).toEqual(
462
542
  resFull.data.feeds,
@@ -468,7 +548,13 @@ describe('feed generation', () => {
468
548
  it('resolves basic feed contents.', async () => {
469
549
  const feed = await agent.api.app.bsky.feed.getFeed(
470
550
  { feed: feedUriEven },
471
- { headers: await network.serviceHeaders(alice, gen.did) },
551
+ {
552
+ headers: await network.serviceHeaders(
553
+ alice,
554
+ ids.AppBskyFeedGetFeed,
555
+ gen.did,
556
+ ),
557
+ },
472
558
  )
473
559
  expect(feed.data.feed.map((item) => item.post.uri)).toEqual([
474
560
  sc.posts[sc.dids.alice][0].ref.uriStr,
@@ -493,7 +579,13 @@ describe('feed generation', () => {
493
579
  const paginator = async (cursor?: string) => {
494
580
  const res = await agent.api.app.bsky.feed.getFeed(
495
581
  { feed: feedUriAll, cursor, limit: 2 },
496
- { headers: await network.serviceHeaders(alice, gen.did) },
582
+ {
583
+ headers: await network.serviceHeaders(
584
+ alice,
585
+ ids.AppBskyFeedGetFeed,
586
+ gen.did,
587
+ ),
588
+ },
497
589
  )
498
590
  return res.data
499
591
  }
@@ -514,7 +606,13 @@ describe('feed generation', () => {
514
606
  it('paginates, handling feed not respecting limit.', async () => {
515
607
  const res = await agent.api.app.bsky.feed.getFeed(
516
608
  { feed: feedUriBadPagination, limit: 3 },
517
- { headers: await network.serviceHeaders(alice, gen.did) },
609
+ {
610
+ headers: await network.serviceHeaders(
611
+ alice,
612
+ ids.AppBskyFeedGetFeed,
613
+ gen.did,
614
+ ),
615
+ },
518
616
  )
519
617
  // refused to respect pagination limit, so it got cut short by appview but the cursor remains.
520
618
  expect(res.data.feed.length).toBeLessThanOrEqual(3)
@@ -529,7 +627,13 @@ describe('feed generation', () => {
529
627
  it('fails on unknown feed.', async () => {
530
628
  const tryGetFeed = agent.api.app.bsky.feed.getFeed(
531
629
  { feed: feedUriOdd },
532
- { headers: await network.serviceHeaders(alice, gen.did) },
630
+ {
631
+ headers: await network.serviceHeaders(
632
+ alice,
633
+ ids.AppBskyFeedGetFeed,
634
+ gen.did,
635
+ ),
636
+ },
533
637
  )
534
638
  await expect(tryGetFeed).rejects.toMatchObject({
535
639
  error: 'UnknownFeed',
@@ -539,7 +643,9 @@ describe('feed generation', () => {
539
643
  it('resolves contents of taken-down feed.', async () => {
540
644
  const tryGetFeed = agent.api.app.bsky.feed.getFeed(
541
645
  { feed: feedUriPrime },
542
- { headers: await network.serviceHeaders(alice) },
646
+ {
647
+ headers: await network.serviceHeaders(alice, ids.AppBskyFeedGetFeed),
648
+ },
543
649
  )
544
650
  await expect(tryGetFeed).resolves.toBeDefined()
545
651
  })
@@ -547,19 +653,19 @@ describe('feed generation', () => {
547
653
  it('receives proper auth details.', async () => {
548
654
  const feed = await agent.api.app.bsky.feed.getFeed(
549
655
  { feed: feedUriEven },
550
- { headers: await network.serviceHeaders(alice, gen.did) },
656
+ {
657
+ headers: await network.serviceHeaders(
658
+ alice,
659
+ ids.AppBskyFeedGetFeedSkeleton,
660
+ gen.did,
661
+ ),
662
+ },
551
663
  )
552
664
  expect(feed.data['$auth']?.['aud']).toEqual(gen.did)
553
665
  expect(feed.data['$auth']?.['iss']).toEqual(alice)
554
- })
555
-
556
- it('receives proper auth details.', async () => {
557
- const feed = await agent.api.app.bsky.feed.getFeed(
558
- { feed: feedUriEven },
559
- { headers: await network.serviceHeaders(alice, gen.did) },
666
+ expect(feed.data['$auth']?.['lxm']).toEqual(
667
+ ids.AppBskyFeedGetFeedSkeleton,
560
668
  )
561
- expect(feed.data['$auth']?.['aud']).toEqual(gen.did)
562
- expect(feed.data['$auth']?.['iss']).toEqual(alice)
563
669
  })
564
670
 
565
671
  it('passes through auth error from feed.', async () => {
@@ -575,7 +681,13 @@ describe('feed generation', () => {
575
681
  it('provides timing info in server-timing header.', async () => {
576
682
  const result = await agent.api.app.bsky.feed.getFeed(
577
683
  { feed: feedUriEven },
578
- { headers: await network.serviceHeaders(alice, gen.did) },
684
+ {
685
+ headers: await network.serviceHeaders(
686
+ alice,
687
+ ids.AppBskyFeedGetFeed,
688
+ gen.did,
689
+ ),
690
+ },
579
691
  )
580
692
  expect(result.headers['server-timing']).toMatch(
581
693
  /^skele;dur=\d+, hydr;dur=\d+$/,
@@ -586,7 +698,13 @@ describe('feed generation', () => {
586
698
  await gen.close() // @NOTE must be last test
587
699
  const tryGetFeed = agent.api.app.bsky.feed.getFeed(
588
700
  { feed: feedUriEven },
589
- { headers: await network.serviceHeaders(alice, gen.did) },
701
+ {
702
+ headers: await network.serviceHeaders(
703
+ alice,
704
+ ids.AppBskyFeedGetFeed,
705
+ gen.did,
706
+ ),
707
+ },
590
708
  )
591
709
  await expect(tryGetFeed).rejects.toThrow('feed unavailable')
592
710
  })
@@ -0,0 +1,186 @@
1
+ import { TestNetwork, SeedClient, RecordRef } from '@atproto/dev-env'
2
+ import AtpAgent, { AppBskyEmbedRecord } from '@atproto/api'
3
+
4
+ import { ids } from '../src/lexicon/lexicons'
5
+ import { postgatesSeed, Users } from './seed/postgates'
6
+
7
+ describe('postgates', () => {
8
+ let network: TestNetwork
9
+ let agent: AtpAgent
10
+ let pdsAgent: AtpAgent
11
+ let sc: SeedClient
12
+ let users: Users
13
+
14
+ beforeAll(async () => {
15
+ network = await TestNetwork.create({
16
+ dbPostgresSchema: 'bsky_tests_postgates',
17
+ })
18
+ agent = network.bsky.getClient()
19
+ pdsAgent = network.pds.getClient()
20
+ sc = network.getSeedClient()
21
+
22
+ const result = await postgatesSeed(sc)
23
+ users = result.users
24
+
25
+ await network.processAll()
26
+ })
27
+
28
+ afterAll(async () => {
29
+ await network.close()
30
+ })
31
+
32
+ describe(`quotee <-> quoter`, () => {
33
+ it(`quotee detaches own post from quoter`, async () => {
34
+ const quoteePost = await sc.post(users.quotee.did, `post`)
35
+ const quoterPost = await sc.post(
36
+ users.quoter.did,
37
+ `quote post`,
38
+ undefined,
39
+ undefined,
40
+ quoteePost.ref,
41
+ )
42
+ await pdsAgent.api.app.bsky.feed.postgate.create(
43
+ {
44
+ repo: users.quotee.did,
45
+ rkey: quoteePost.ref.uri.rkey,
46
+ },
47
+ {
48
+ post: quoteePost.ref.uriStr,
49
+ createdAt: new Date().toISOString(),
50
+ detachedEmbeddingUris: [quoterPost.ref.uriStr],
51
+ },
52
+ sc.getHeaders(users.quotee.did),
53
+ )
54
+ await network.processAll()
55
+
56
+ const root = await agent.api.app.bsky.feed.getPostThread(
57
+ { uri: quoterPost.ref.uriStr },
58
+ {
59
+ headers: await network.serviceHeaders(
60
+ users.viewer.did,
61
+ ids.AppBskyFeedGetPostThread,
62
+ ),
63
+ },
64
+ )
65
+
66
+ expect(
67
+ // @ts-ignore I know more than you
68
+ AppBskyEmbedRecord.isViewDetached(root.data.thread.post.embed.record),
69
+ ).toBe(true)
70
+ })
71
+
72
+ it(`postgate made by bystander has no effect`, async () => {
73
+ const quoteePost = await sc.post(users.quotee.did, `post`)
74
+ const quoterPost = await sc.post(
75
+ users.quoter.did,
76
+ `quote post`,
77
+ undefined,
78
+ undefined,
79
+ quoteePost.ref,
80
+ )
81
+ await pdsAgent.api.app.bsky.feed.postgate.create(
82
+ {
83
+ repo: users.viewer.did,
84
+ rkey: quoteePost.ref.uri.rkey,
85
+ },
86
+ {
87
+ post: quoteePost.ref.uriStr,
88
+ createdAt: new Date().toISOString(),
89
+ detachedEmbeddingUris: [quoterPost.ref.uriStr],
90
+ },
91
+ sc.getHeaders(users.viewer.did),
92
+ )
93
+ await network.processAll()
94
+
95
+ const root = await agent.api.app.bsky.feed.getPostThread(
96
+ { uri: quoterPost.ref.uriStr },
97
+ {
98
+ headers: await network.serviceHeaders(
99
+ users.viewer.did,
100
+ ids.AppBskyFeedGetPostThread,
101
+ ),
102
+ },
103
+ )
104
+
105
+ expect(
106
+ // @ts-ignore I know more than you
107
+ AppBskyEmbedRecord.isViewDetached(root.data.thread.post.embed.record),
108
+ ).toBe(false)
109
+ })
110
+ })
111
+
112
+ describe(`embeddingRules`, () => {
113
+ it(`disables quoteposts`, async () => {
114
+ const quoteePost = await sc.post(users.quotee.did, `post`)
115
+ await pdsAgent.api.app.bsky.feed.postgate.create(
116
+ {
117
+ repo: users.quotee.did,
118
+ rkey: quoteePost.ref.uri.rkey,
119
+ },
120
+ {
121
+ post: quoteePost.ref.uriStr,
122
+ createdAt: new Date().toISOString(),
123
+ embeddingRules: [{ $type: 'app.bsky.feed.postgate#disableRule' }],
124
+ },
125
+ sc.getHeaders(users.quotee.did),
126
+ )
127
+ await network.processAll()
128
+
129
+ const root = await agent.api.app.bsky.feed.getPostThread(
130
+ { uri: quoteePost.ref.uriStr },
131
+ {
132
+ headers: await network.serviceHeaders(
133
+ users.viewer.did,
134
+ ids.AppBskyFeedGetPostThread,
135
+ ),
136
+ },
137
+ )
138
+
139
+ expect(
140
+ // @ts-ignore I know more than you
141
+ root.data.thread.post.viewer.embeddingDisabled,
142
+ ).toBe(true)
143
+ })
144
+
145
+ it(`quotepost created after quotes disabled hides embed`, async () => {
146
+ const quoteePost = await sc.post(users.quotee.did, `post`)
147
+ await pdsAgent.api.app.bsky.feed.postgate.create(
148
+ {
149
+ repo: users.quotee.did,
150
+ rkey: quoteePost.ref.uri.rkey,
151
+ },
152
+ {
153
+ post: quoteePost.ref.uriStr,
154
+ createdAt: new Date().toISOString(),
155
+ embeddingRules: [{ $type: 'app.bsky.feed.postgate#disableRule' }],
156
+ },
157
+ sc.getHeaders(users.quotee.did),
158
+ )
159
+ await network.processAll()
160
+
161
+ const quoterPost = await sc.post(
162
+ users.quoter.did,
163
+ `quote post`,
164
+ undefined,
165
+ undefined,
166
+ quoteePost.ref,
167
+ )
168
+ await network.processAll()
169
+
170
+ const root = await agent.api.app.bsky.feed.getPostThread(
171
+ { uri: quoterPost.ref.uriStr },
172
+ {
173
+ headers: await network.serviceHeaders(
174
+ users.viewer.did,
175
+ ids.AppBskyFeedGetPostThread,
176
+ ),
177
+ },
178
+ )
179
+
180
+ expect(
181
+ // @ts-ignore I know more than you
182
+ AppBskyEmbedRecord.isViewDetached(root.data.thread.post.embed.record),
183
+ ).toBe(true)
184
+ })
185
+ })
186
+ })
@@ -0,0 +1,62 @@
1
+ import { TestNetwork, SeedClient, TestNetworkNoAppView } from '@atproto/dev-env'
2
+
3
+ export type User = {
4
+ id: string
5
+ did: string
6
+ email: string
7
+ handle: string
8
+ password: string
9
+ displayName: string
10
+ description: string
11
+ selfLabels: undefined
12
+ }
13
+
14
+ function createUser(name: string): User {
15
+ return {
16
+ id: name,
17
+ // @ts-ignore overwritten below
18
+ did: undefined,
19
+ email: `${name}@test.com`,
20
+ handle: `${name}.test`,
21
+ password: `${name}-pass`,
22
+ displayName: name,
23
+ description: `hi im ${name} label_me`,
24
+ selfLabels: undefined,
25
+ }
26
+ }
27
+
28
+ const users = {
29
+ viewer: createUser('viewer'),
30
+
31
+ poster: createUser('poster'),
32
+ replier: createUser('replier'),
33
+ reposter: createUser('reposter'),
34
+ }
35
+
36
+ export type Users = typeof users
37
+
38
+ export async function feedHiddenRepliesSeed(
39
+ sc: SeedClient<TestNetwork | TestNetworkNoAppView>,
40
+ ) {
41
+ const u = structuredClone(users)
42
+
43
+ await sc.createAccount('poster', u.poster)
44
+ await sc.createAccount('replier', u.replier)
45
+ await sc.createAccount('viewer', u.viewer)
46
+ await sc.createAccount('reposter', u.reposter)
47
+
48
+ Object.values(u).forEach((user) => {
49
+ u[user.id].did = sc.dids[user.id]
50
+ })
51
+
52
+ await sc.follow(u.viewer.did, u.poster.did)
53
+ await sc.follow(u.viewer.did, u.replier.did)
54
+ await sc.follow(u.viewer.did, u.reposter.did)
55
+
56
+ await sc.network.processAll()
57
+
58
+ return {
59
+ users: u,
60
+ seedClient: sc,
61
+ }
62
+ }