@atproto/bsky 0.4.0 → 0.5.0

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 (264) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/dist/api/app/bsky/actor/getProfile.d.ts.map +1 -1
  3. package/dist/api/app/bsky/actor/getProfile.js +1 -0
  4. package/dist/api/app/bsky/actor/getProfile.js.map +1 -1
  5. package/dist/api/app/bsky/actor/getProfiles.d.ts.map +1 -1
  6. package/dist/api/app/bsky/actor/getProfiles.js +1 -0
  7. package/dist/api/app/bsky/actor/getProfiles.js.map +1 -1
  8. package/dist/api/app/bsky/actor/getSuggestions.d.ts.map +1 -1
  9. package/dist/api/app/bsky/actor/getSuggestions.js +1 -0
  10. package/dist/api/app/bsky/actor/getSuggestions.js.map +1 -1
  11. package/dist/api/app/bsky/actor/searchActors.d.ts.map +1 -1
  12. package/dist/api/app/bsky/actor/searchActors.js +1 -0
  13. package/dist/api/app/bsky/actor/searchActors.js.map +1 -1
  14. package/dist/api/app/bsky/actor/searchActorsTypeahead.d.ts.map +1 -1
  15. package/dist/api/app/bsky/actor/searchActorsTypeahead.js +1 -0
  16. package/dist/api/app/bsky/actor/searchActorsTypeahead.js.map +1 -1
  17. package/dist/api/app/bsky/bookmark/getBookmarks.d.ts.map +1 -1
  18. package/dist/api/app/bsky/bookmark/getBookmarks.js +1 -0
  19. package/dist/api/app/bsky/bookmark/getBookmarks.js.map +1 -1
  20. package/dist/api/app/bsky/contact/getMatches.d.ts.map +1 -1
  21. package/dist/api/app/bsky/contact/getMatches.js +1 -0
  22. package/dist/api/app/bsky/contact/getMatches.js.map +1 -1
  23. package/dist/api/app/bsky/contact/importContacts.d.ts.map +1 -1
  24. package/dist/api/app/bsky/contact/importContacts.js +1 -0
  25. package/dist/api/app/bsky/contact/importContacts.js.map +1 -1
  26. package/dist/api/app/bsky/feed/getActorFeeds.d.ts.map +1 -1
  27. package/dist/api/app/bsky/feed/getActorFeeds.js +5 -1
  28. package/dist/api/app/bsky/feed/getActorFeeds.js.map +1 -1
  29. package/dist/api/app/bsky/feed/getActorLikes.d.ts.map +1 -1
  30. package/dist/api/app/bsky/feed/getActorLikes.js +1 -0
  31. package/dist/api/app/bsky/feed/getActorLikes.js.map +1 -1
  32. package/dist/api/app/bsky/feed/getAuthorFeed.d.ts.map +1 -1
  33. package/dist/api/app/bsky/feed/getAuthorFeed.js +1 -0
  34. package/dist/api/app/bsky/feed/getAuthorFeed.js.map +1 -1
  35. package/dist/api/app/bsky/feed/getFeed.d.ts.map +1 -1
  36. package/dist/api/app/bsky/feed/getFeed.js +1 -0
  37. package/dist/api/app/bsky/feed/getFeed.js.map +1 -1
  38. package/dist/api/app/bsky/feed/getFeedGenerator.d.ts.map +1 -1
  39. package/dist/api/app/bsky/feed/getFeedGenerator.js +5 -1
  40. package/dist/api/app/bsky/feed/getFeedGenerator.js.map +1 -1
  41. package/dist/api/app/bsky/feed/getFeedGenerators.d.ts.map +1 -1
  42. package/dist/api/app/bsky/feed/getFeedGenerators.js +5 -1
  43. package/dist/api/app/bsky/feed/getFeedGenerators.js.map +1 -1
  44. package/dist/api/app/bsky/feed/getLikes.d.ts.map +1 -1
  45. package/dist/api/app/bsky/feed/getLikes.js +1 -0
  46. package/dist/api/app/bsky/feed/getLikes.js.map +1 -1
  47. package/dist/api/app/bsky/feed/getListFeed.d.ts.map +1 -1
  48. package/dist/api/app/bsky/feed/getListFeed.js +1 -0
  49. package/dist/api/app/bsky/feed/getListFeed.js.map +1 -1
  50. package/dist/api/app/bsky/feed/getPostThread.d.ts.map +1 -1
  51. package/dist/api/app/bsky/feed/getPostThread.js +1 -0
  52. package/dist/api/app/bsky/feed/getPostThread.js.map +1 -1
  53. package/dist/api/app/bsky/feed/getPosts.d.ts.map +1 -1
  54. package/dist/api/app/bsky/feed/getPosts.js +5 -1
  55. package/dist/api/app/bsky/feed/getPosts.js.map +1 -1
  56. package/dist/api/app/bsky/feed/getQuotes.d.ts.map +1 -1
  57. package/dist/api/app/bsky/feed/getQuotes.js +1 -0
  58. package/dist/api/app/bsky/feed/getQuotes.js.map +1 -1
  59. package/dist/api/app/bsky/feed/getRepostedBy.d.ts.map +1 -1
  60. package/dist/api/app/bsky/feed/getRepostedBy.js +1 -0
  61. package/dist/api/app/bsky/feed/getRepostedBy.js.map +1 -1
  62. package/dist/api/app/bsky/feed/getSuggestedFeeds.d.ts.map +1 -1
  63. package/dist/api/app/bsky/feed/getSuggestedFeeds.js +5 -1
  64. package/dist/api/app/bsky/feed/getSuggestedFeeds.js.map +1 -1
  65. package/dist/api/app/bsky/feed/getTimeline.d.ts.map +1 -1
  66. package/dist/api/app/bsky/feed/getTimeline.js +1 -0
  67. package/dist/api/app/bsky/feed/getTimeline.js.map +1 -1
  68. package/dist/api/app/bsky/feed/searchPosts.d.ts.map +1 -1
  69. package/dist/api/app/bsky/feed/searchPosts.js +1 -0
  70. package/dist/api/app/bsky/feed/searchPosts.js.map +1 -1
  71. package/dist/api/app/bsky/feed/searchPostsV2.d.ts.map +1 -1
  72. package/dist/api/app/bsky/feed/searchPostsV2.js +1 -0
  73. package/dist/api/app/bsky/feed/searchPostsV2.js.map +1 -1
  74. package/dist/api/app/bsky/graph/getActorStarterPacks.d.ts.map +1 -1
  75. package/dist/api/app/bsky/graph/getActorStarterPacks.js +1 -0
  76. package/dist/api/app/bsky/graph/getActorStarterPacks.js.map +1 -1
  77. package/dist/api/app/bsky/graph/getBlocks.d.ts.map +1 -1
  78. package/dist/api/app/bsky/graph/getBlocks.js +5 -1
  79. package/dist/api/app/bsky/graph/getBlocks.js.map +1 -1
  80. package/dist/api/app/bsky/graph/getFollowers.d.ts.map +1 -1
  81. package/dist/api/app/bsky/graph/getFollowers.js +1 -0
  82. package/dist/api/app/bsky/graph/getFollowers.js.map +1 -1
  83. package/dist/api/app/bsky/graph/getFollows.d.ts.map +1 -1
  84. package/dist/api/app/bsky/graph/getFollows.js +1 -0
  85. package/dist/api/app/bsky/graph/getFollows.js.map +1 -1
  86. package/dist/api/app/bsky/graph/getKnownFollowers.d.ts.map +1 -1
  87. package/dist/api/app/bsky/graph/getKnownFollowers.js +1 -0
  88. package/dist/api/app/bsky/graph/getKnownFollowers.js.map +1 -1
  89. package/dist/api/app/bsky/graph/getList.d.ts.map +1 -1
  90. package/dist/api/app/bsky/graph/getList.js +1 -0
  91. package/dist/api/app/bsky/graph/getList.js.map +1 -1
  92. package/dist/api/app/bsky/graph/getListBlocks.d.ts.map +1 -1
  93. package/dist/api/app/bsky/graph/getListBlocks.js +5 -1
  94. package/dist/api/app/bsky/graph/getListBlocks.js.map +1 -1
  95. package/dist/api/app/bsky/graph/getListMutes.d.ts.map +1 -1
  96. package/dist/api/app/bsky/graph/getListMutes.js +5 -1
  97. package/dist/api/app/bsky/graph/getListMutes.js.map +1 -1
  98. package/dist/api/app/bsky/graph/getLists.d.ts.map +1 -1
  99. package/dist/api/app/bsky/graph/getLists.js +1 -0
  100. package/dist/api/app/bsky/graph/getLists.js.map +1 -1
  101. package/dist/api/app/bsky/graph/getListsWithMembership.d.ts.map +1 -1
  102. package/dist/api/app/bsky/graph/getListsWithMembership.js +1 -0
  103. package/dist/api/app/bsky/graph/getListsWithMembership.js.map +1 -1
  104. package/dist/api/app/bsky/graph/getMutes.d.ts.map +1 -1
  105. package/dist/api/app/bsky/graph/getMutes.js +5 -1
  106. package/dist/api/app/bsky/graph/getMutes.js.map +1 -1
  107. package/dist/api/app/bsky/graph/getStarterPack.d.ts.map +1 -1
  108. package/dist/api/app/bsky/graph/getStarterPack.js +1 -0
  109. package/dist/api/app/bsky/graph/getStarterPack.js.map +1 -1
  110. package/dist/api/app/bsky/graph/getStarterPacks.d.ts.map +1 -1
  111. package/dist/api/app/bsky/graph/getStarterPacks.js +1 -0
  112. package/dist/api/app/bsky/graph/getStarterPacks.js.map +1 -1
  113. package/dist/api/app/bsky/graph/getStarterPacksWithMembership.d.ts.map +1 -1
  114. package/dist/api/app/bsky/graph/getStarterPacksWithMembership.js +1 -0
  115. package/dist/api/app/bsky/graph/getStarterPacksWithMembership.js.map +1 -1
  116. package/dist/api/app/bsky/graph/getSuggestedFollowsByActor.d.ts.map +1 -1
  117. package/dist/api/app/bsky/graph/getSuggestedFollowsByActor.js +1 -0
  118. package/dist/api/app/bsky/graph/getSuggestedFollowsByActor.js.map +1 -1
  119. package/dist/api/app/bsky/graph/searchStarterPacks.d.ts.map +1 -1
  120. package/dist/api/app/bsky/graph/searchStarterPacks.js +1 -0
  121. package/dist/api/app/bsky/graph/searchStarterPacks.js.map +1 -1
  122. package/dist/api/app/bsky/graph/searchStarterPacksV2.d.ts.map +1 -1
  123. package/dist/api/app/bsky/graph/searchStarterPacksV2.js +1 -0
  124. package/dist/api/app/bsky/graph/searchStarterPacksV2.js.map +1 -1
  125. package/dist/api/app/bsky/labeler/getServices.d.ts.map +1 -1
  126. package/dist/api/app/bsky/labeler/getServices.js +1 -0
  127. package/dist/api/app/bsky/labeler/getServices.js.map +1 -1
  128. package/dist/api/app/bsky/notification/getGroupedNotifications.d.ts.map +1 -1
  129. package/dist/api/app/bsky/notification/getGroupedNotifications.js +29 -19
  130. package/dist/api/app/bsky/notification/getGroupedNotifications.js.map +1 -1
  131. package/dist/api/app/bsky/notification/grouping/algoGravity.d.ts +4 -3
  132. package/dist/api/app/bsky/notification/grouping/algoGravity.d.ts.map +1 -1
  133. package/dist/api/app/bsky/notification/grouping/algoGravity.js +53 -42
  134. package/dist/api/app/bsky/notification/grouping/algoGravity.js.map +1 -1
  135. package/dist/api/app/bsky/notification/grouping/algoLookback.d.ts +4 -3
  136. package/dist/api/app/bsky/notification/grouping/algoLookback.d.ts.map +1 -1
  137. package/dist/api/app/bsky/notification/grouping/algoLookback.js +56 -42
  138. package/dist/api/app/bsky/notification/grouping/algoLookback.js.map +1 -1
  139. package/dist/api/app/bsky/notification/grouping/grouping.d.ts +12 -2
  140. package/dist/api/app/bsky/notification/grouping/grouping.d.ts.map +1 -1
  141. package/dist/api/app/bsky/notification/grouping/grouping.js +20 -6
  142. package/dist/api/app/bsky/notification/grouping/grouping.js.map +1 -1
  143. package/dist/api/app/bsky/notification/grouping/spotlight.d.ts +2 -2
  144. package/dist/api/app/bsky/notification/grouping/spotlight.d.ts.map +1 -1
  145. package/dist/api/app/bsky/notification/grouping/spotlight.js +35 -22
  146. package/dist/api/app/bsky/notification/grouping/spotlight.js.map +1 -1
  147. package/dist/api/app/bsky/notification/listActivitySubscriptions.d.ts.map +1 -1
  148. package/dist/api/app/bsky/notification/listActivitySubscriptions.js +1 -0
  149. package/dist/api/app/bsky/notification/listActivitySubscriptions.js.map +1 -1
  150. package/dist/api/app/bsky/notification/listNotifications.d.ts.map +1 -1
  151. package/dist/api/app/bsky/notification/listNotifications.js +5 -1
  152. package/dist/api/app/bsky/notification/listNotifications.js.map +1 -1
  153. package/dist/api/app/bsky/unspecced/atmosphere-grouping.d.ts +16 -0
  154. package/dist/api/app/bsky/unspecced/atmosphere-grouping.d.ts.map +1 -0
  155. package/dist/api/app/bsky/unspecced/atmosphere-grouping.js +124 -0
  156. package/dist/api/app/bsky/unspecced/atmosphere-grouping.js.map +1 -0
  157. package/dist/api/app/bsky/unspecced/atmosphere-hydration.d.ts +32 -0
  158. package/dist/api/app/bsky/unspecced/atmosphere-hydration.d.ts.map +1 -0
  159. package/dist/api/app/bsky/unspecced/atmosphere-hydration.js +201 -0
  160. package/dist/api/app/bsky/unspecced/atmosphere-hydration.js.map +1 -0
  161. package/dist/api/app/bsky/unspecced/atmosphere-pagination.d.ts +6 -0
  162. package/dist/api/app/bsky/unspecced/atmosphere-pagination.d.ts.map +1 -0
  163. package/dist/api/app/bsky/unspecced/atmosphere-pagination.js +164 -0
  164. package/dist/api/app/bsky/unspecced/atmosphere-pagination.js.map +1 -0
  165. package/dist/api/app/bsky/unspecced/getAtmosphereExploreTab.d.ts.map +1 -1
  166. package/dist/api/app/bsky/unspecced/getAtmosphereExploreTab.js +120 -55
  167. package/dist/api/app/bsky/unspecced/getAtmosphereExploreTab.js.map +1 -1
  168. package/dist/api/app/bsky/unspecced/getAtmosphereTimeline.d.ts +4 -0
  169. package/dist/api/app/bsky/unspecced/getAtmosphereTimeline.d.ts.map +1 -0
  170. package/dist/api/app/bsky/unspecced/getAtmosphereTimeline.js +30 -0
  171. package/dist/api/app/bsky/unspecced/getAtmosphereTimeline.js.map +1 -0
  172. package/dist/api/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.d.ts.map +1 -1
  173. package/dist/api/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.js +4 -7
  174. package/dist/api/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.js.map +1 -1
  175. package/dist/api/app/bsky/unspecced/getPopularFeedGenerators.d.ts.map +1 -1
  176. package/dist/api/app/bsky/unspecced/getPopularFeedGenerators.js +1 -0
  177. package/dist/api/app/bsky/unspecced/getPopularFeedGenerators.js.map +1 -1
  178. package/dist/api/app/bsky/unspecced/getPostThreadOtherV2.d.ts.map +1 -1
  179. package/dist/api/app/bsky/unspecced/getPostThreadOtherV2.js +1 -0
  180. package/dist/api/app/bsky/unspecced/getPostThreadOtherV2.js.map +1 -1
  181. package/dist/api/app/bsky/unspecced/getPostThreadV2.d.ts.map +1 -1
  182. package/dist/api/app/bsky/unspecced/getPostThreadV2.js +1 -0
  183. package/dist/api/app/bsky/unspecced/getPostThreadV2.js.map +1 -1
  184. package/dist/api/app/bsky/unspecced/getSuggestedFeeds.d.ts.map +1 -1
  185. package/dist/api/app/bsky/unspecced/getSuggestedFeeds.js +4 -7
  186. package/dist/api/app/bsky/unspecced/getSuggestedFeeds.js.map +1 -1
  187. package/dist/api/app/bsky/unspecced/getSuggestedOnboardingUsers.d.ts.map +1 -1
  188. package/dist/api/app/bsky/unspecced/getSuggestedOnboardingUsers.js +1 -0
  189. package/dist/api/app/bsky/unspecced/getSuggestedOnboardingUsers.js.map +1 -1
  190. package/dist/api/app/bsky/unspecced/getSuggestedStarterPacks.d.ts.map +1 -1
  191. package/dist/api/app/bsky/unspecced/getSuggestedStarterPacks.js +4 -7
  192. package/dist/api/app/bsky/unspecced/getSuggestedStarterPacks.js.map +1 -1
  193. package/dist/api/app/bsky/unspecced/getSuggestedUsers.d.ts.map +1 -1
  194. package/dist/api/app/bsky/unspecced/getSuggestedUsers.js +2 -19
  195. package/dist/api/app/bsky/unspecced/getSuggestedUsers.js.map +1 -1
  196. package/dist/api/app/bsky/unspecced/getSuggestedUsersForDiscover.d.ts.map +1 -1
  197. package/dist/api/app/bsky/unspecced/getSuggestedUsersForDiscover.js +1 -0
  198. package/dist/api/app/bsky/unspecced/getSuggestedUsersForDiscover.js.map +1 -1
  199. package/dist/api/app/bsky/unspecced/getSuggestedUsersForExplore.d.ts.map +1 -1
  200. package/dist/api/app/bsky/unspecced/getSuggestedUsersForExplore.js +1 -0
  201. package/dist/api/app/bsky/unspecced/getSuggestedUsersForExplore.js.map +1 -1
  202. package/dist/api/app/bsky/unspecced/getSuggestedUsersForSeeMore.d.ts.map +1 -1
  203. package/dist/api/app/bsky/unspecced/getSuggestedUsersForSeeMore.js +1 -0
  204. package/dist/api/app/bsky/unspecced/getSuggestedUsersForSeeMore.js.map +1 -1
  205. package/dist/api/app/bsky/unspecced/getTrendingTopics.d.ts.map +1 -1
  206. package/dist/api/app/bsky/unspecced/getTrendingTopics.js +6 -2
  207. package/dist/api/app/bsky/unspecced/getTrendingTopics.js.map +1 -1
  208. package/dist/api/app/bsky/unspecced/getTrends.d.ts.map +1 -1
  209. package/dist/api/app/bsky/unspecced/getTrends.js +6 -2
  210. package/dist/api/app/bsky/unspecced/getTrends.js.map +1 -1
  211. package/dist/api/index.d.ts.map +1 -1
  212. package/dist/api/index.js +2 -0
  213. package/dist/api/index.js.map +1 -1
  214. package/dist/api/internal/bsky/actor/getProfiles.d.ts.map +1 -1
  215. package/dist/api/internal/bsky/actor/getProfiles.js +1 -0
  216. package/dist/api/internal/bsky/actor/getProfiles.js.map +1 -1
  217. package/dist/config.d.ts +0 -4
  218. package/dist/config.d.ts.map +1 -1
  219. package/dist/config.js +0 -10
  220. package/dist/config.js.map +1 -1
  221. package/dist/context.d.ts +0 -2
  222. package/dist/context.d.ts.map +1 -1
  223. package/dist/context.js +0 -3
  224. package/dist/context.js.map +1 -1
  225. package/dist/feature-gates/gates.d.ts +0 -4
  226. package/dist/feature-gates/gates.d.ts.map +1 -1
  227. package/dist/feature-gates/gates.js +0 -4
  228. package/dist/feature-gates/gates.js.map +1 -1
  229. package/dist/hydration/external.d.ts +8 -2
  230. package/dist/hydration/external.d.ts.map +1 -1
  231. package/dist/hydration/external.js +2 -0
  232. package/dist/hydration/external.js.map +1 -1
  233. package/dist/hydration/hydrator.d.ts +6 -2
  234. package/dist/hydration/hydrator.d.ts.map +1 -1
  235. package/dist/hydration/hydrator.js +96 -29
  236. package/dist/hydration/hydrator.js.map +1 -1
  237. package/dist/index.d.ts.map +1 -1
  238. package/dist/index.js +4 -19
  239. package/dist/index.js.map +1 -1
  240. package/dist/lexicons/app/bsky/unspecced/getAtmosphereExploreTab.defs.d.ts +29 -0
  241. package/dist/lexicons/app/bsky/unspecced/getAtmosphereExploreTab.defs.d.ts.map +1 -1
  242. package/dist/lexicons/app/bsky/unspecced/getAtmosphereExploreTab.defs.js +2 -1
  243. package/dist/lexicons/app/bsky/unspecced/getAtmosphereExploreTab.defs.js.map +1 -1
  244. package/dist/lexicons/app/bsky/unspecced/getAtmosphereTimeline.d.ts +3 -0
  245. package/dist/lexicons/app/bsky/unspecced/getAtmosphereTimeline.d.ts.map +1 -0
  246. package/dist/lexicons/app/bsky/unspecced/getAtmosphereTimeline.defs.d.ts +85 -0
  247. package/dist/lexicons/app/bsky/unspecced/getAtmosphereTimeline.defs.d.ts.map +1 -0
  248. package/dist/lexicons/app/bsky/unspecced/getAtmosphereTimeline.defs.js +29 -0
  249. package/dist/lexicons/app/bsky/unspecced/getAtmosphereTimeline.defs.js.map +1 -0
  250. package/dist/lexicons/app/bsky/unspecced/getAtmosphereTimeline.js +6 -0
  251. package/dist/lexicons/app/bsky/unspecced/getAtmosphereTimeline.js.map +1 -0
  252. package/dist/lexicons/app/bsky/unspecced.d.ts +1 -0
  253. package/dist/lexicons/app/bsky/unspecced.d.ts.map +1 -1
  254. package/dist/lexicons/app/bsky/unspecced.js +1 -0
  255. package/dist/lexicons/app/bsky/unspecced.js.map +1 -1
  256. package/dist/telemetry/events.d.ts +5 -4
  257. package/dist/telemetry/events.d.ts.map +1 -1
  258. package/dist/telemetry/events.js +13 -2
  259. package/dist/telemetry/events.js.map +1 -1
  260. package/dist/views/external.d.ts +5 -0
  261. package/dist/views/external.d.ts.map +1 -1
  262. package/dist/views/external.js +38 -11
  263. package/dist/views/external.js.map +1 -1
  264. package/package.json +6 -6
@@ -15,6 +15,7 @@ export default function (server, ctx) {
15
15
  const { viewer, includeTakedowns, skipViewerBlocks } = ctx.authVerifier.parseCreds(auth);
16
16
  const labelers = ctx.reqLabelers(req);
17
17
  const hydrateCtx = await ctx.hydrator.createContext({
18
+ xrpcEndpoint: app.bsky.feed.getAuthorFeed.$lxm,
18
19
  labelers,
19
20
  viewer,
20
21
  includeTakedowns,
@@ -1 +1 @@
1
- {"version":3,"file":"getAuthorFeed.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/feed/getAuthorFeed.ts"],"names":[],"mappings":"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","sourcesContent":["import { mapDefined } from '@atproto/common'\nimport type { AtUriString } from '@atproto/lex'\nimport { InvalidRequestError, type Server } from '@atproto/xrpc-server'\nimport type { AppContext } from '../../../../context.js'\nimport type { DataPlaneClient } from '../../../../data-plane/index.js'\nimport type { Actor } from '../../../../hydration/actor.js'\nimport type { FeedItem, Post } from '../../../../hydration/feed.js'\nimport {\n type HydrateCtx,\n type HydrationState,\n type Hydrator,\n mergeStates,\n} from '../../../../hydration/hydrator.js'\nimport { parseString } from '../../../../hydration/util.js'\nimport { app } from '../../../../lexicons/index.js'\nimport { createPipeline } from '../../../../pipeline.js'\nimport { FeedType } from '../../../../proto/bsky_pb.js'\nimport { safePinnedPost, uriToDid } from '../../../../util/uris.js'\nimport type { Views } from '../../../../views/index.js'\nimport { clearlyBadCursor, fillPage, resHeaders } from '../../../util.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const getAuthorFeed = createPipeline(\n skeleton,\n hydration,\n noBlocksOrMutedReposts,\n presentation,\n )\n server.add(app.bsky.feed.getAuthorFeed, {\n auth: ctx.authVerifier.optionalStandardOrRole,\n handler: async ({ params, auth, req }) => {\n const { viewer, includeTakedowns, skipViewerBlocks } =\n ctx.authVerifier.parseCreds(auth)\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({\n labelers,\n viewer,\n includeTakedowns,\n skipViewerBlocks,\n features: ctx.featureGatesClient.scope(\n ctx.featureGatesClient.parseUserContextFromHandler({ viewer, req }),\n ),\n })\n\n const result = await fillPage({\n cursor: params.cursor,\n limit: params.limit,\n fetch: ({ cursor, limit }) =>\n getAuthorFeed({ ...params, cursor, limit, hydrateCtx }, ctx),\n items: (r) => r.feed,\n })\n\n const repoRev = await ctx.hydrator.actor.getRepoRevSafe(viewer)\n\n return {\n encoding: 'application/json',\n body: result,\n headers: resHeaders({\n repoRev,\n labelers: hydrateCtx.labelers,\n }),\n }\n },\n })\n}\n\nconst FILTER_TO_FEED_TYPE = {\n posts_with_replies: undefined, // default: all posts, replies, and reposts\n posts_no_replies: FeedType.POSTS_NO_REPLIES,\n posts_with_media: FeedType.POSTS_WITH_MEDIA,\n posts_and_author_threads: FeedType.POSTS_AND_AUTHOR_THREADS,\n posts_with_video: FeedType.POSTS_WITH_VIDEO,\n}\n\nexport const skeleton = async (inputs: {\n ctx: Context\n params: Params\n}): Promise<Skeleton> => {\n const { ctx, params } = inputs\n const [did] = await ctx.hydrator.actor.getDids([params.actor])\n if (!did) {\n throw new InvalidRequestError('Profile not found')\n }\n const actors = await ctx.hydrator.actor.getActors([did], {\n includeTakedowns: params.hydrateCtx.includeTakedowns,\n skipCacheForDids: params.hydrateCtx.skipCacheForViewer,\n })\n const actor = actors.get(did)\n if (!actor) {\n throw new InvalidRequestError('Profile not found')\n }\n if (clearlyBadCursor(params.cursor)) {\n return { actor, filter: params.filter, items: [] }\n }\n\n const pinnedPost = safePinnedPost(actor.profile?.pinnedPost)\n const isFirstPageRequest = !params.cursor\n const shouldInsertPinnedPost =\n isFirstPageRequest &&\n params.includePins &&\n pinnedPost &&\n uriToDid(pinnedPost.uri) === actor.did\n\n const res = await ctx.dataplane.getAuthorFeed({\n actorDid: did,\n limit: params.limit,\n cursor: params.cursor,\n feedType: FILTER_TO_FEED_TYPE[params.filter],\n })\n\n let items: FeedItem[] = res.items.map((item) => ({\n post: { uri: item.uri as AtUriString, cid: item.cid || undefined },\n repost: item.repost\n ? { uri: item.repost as AtUriString, cid: item.repostCid || undefined }\n : undefined,\n }))\n\n if (shouldInsertPinnedPost && pinnedPost) {\n const pinnedItem = {\n post: {\n uri: pinnedPost.uri,\n cid: pinnedPost.cid,\n },\n authorPinned: true,\n }\n\n items = items.filter((item) => item.post.uri !== pinnedItem.post.uri)\n items.unshift(pinnedItem)\n }\n\n return {\n actor,\n filter: params.filter,\n items,\n cursor: parseString(res.cursor),\n }\n}\n\nconst hydration = async (inputs: {\n ctx: Context\n params: Params\n skeleton: Skeleton\n}): Promise<HydrationState> => {\n const { ctx, params, skeleton } = inputs\n const [feedPostState, profileViewerState] = await Promise.all([\n ctx.hydrator.hydrateFeedItems(skeleton.items, params.hydrateCtx, {\n knownLikers:\n !!params.hydrateCtx.viewer &&\n params.hydrateCtx.features.checkGate(\n params.hydrateCtx.features.Gate.KnownLikersFeedEnable,\n ),\n }),\n ctx.hydrator.hydrateProfileViewers([skeleton.actor.did], params.hydrateCtx),\n ])\n return mergeStates(feedPostState, profileViewerState)\n}\n\nconst noBlocksOrMutedReposts = (inputs: {\n ctx: Context\n skeleton: Skeleton\n hydration: HydrationState\n}): Skeleton => {\n const { ctx, skeleton, hydration } = inputs\n const relationship = hydration.profileViewers?.get(skeleton.actor.did)\n if (\n !hydration.ctx?.skipViewerBlocks &&\n relationship &&\n (relationship.blocking || ctx.views.blockingByList(relationship, hydration))\n ) {\n throw new InvalidRequestError(\n `Requester has blocked actor: ${skeleton.actor.did}`,\n 'BlockedActor',\n )\n }\n if (\n !hydration.ctx?.skipViewerBlocks &&\n relationship &&\n (relationship.blockedBy || ctx.views.blockedByList(relationship, hydration))\n ) {\n throw new InvalidRequestError(\n `Requester is blocked by actor: ${skeleton.actor.did}`,\n 'BlockedByActor',\n )\n }\n\n const checkBlocksAndMutes = (item: FeedItem) => {\n const bam = ctx.views.feedItemBlocksAndMutes(item, hydration)\n return (\n !bam.authorBlocked &&\n !bam.originatorBlocked &&\n (!bam.authorMuted || bam.originatorMuted) // repost of muted content\n )\n }\n\n if (skeleton.filter === 'posts_and_author_threads') {\n // ensure replies are only included if the feed contains all\n // replies up to the thread root (i.e. a complete self-thread.)\n const selfThread = new SelfThreadTracker(skeleton.items, hydration)\n skeleton.items = skeleton.items.filter((item) => {\n return (\n checkBlocksAndMutes(item) &&\n (item.repost || item.authorPinned || selfThread.ok(item.post.uri))\n )\n })\n } else {\n skeleton.items = skeleton.items.filter(checkBlocksAndMutes)\n }\n\n return skeleton\n}\n\nconst presentation = (inputs: {\n ctx: Context\n skeleton: Skeleton\n hydration: HydrationState\n}) => {\n const { ctx, skeleton, hydration } = inputs\n const feed = mapDefined(skeleton.items, (item) =>\n ctx.views.feedViewPost(item, hydration),\n )\n return { feed, cursor: skeleton.cursor }\n}\n\ntype Context = {\n hydrator: Hydrator\n views: Views\n dataplane: DataPlaneClient\n}\n\ntype Params = app.bsky.feed.getAuthorFeed.$Params & {\n hydrateCtx: HydrateCtx\n}\n\ntype Skeleton = {\n actor: Actor\n items: FeedItem[]\n filter: app.bsky.feed.getAuthorFeed.$Params['filter']\n cursor?: string\n}\n\nclass SelfThreadTracker {\n feedUris = new Set<AtUriString>()\n cache = new Map<AtUriString, boolean>()\n\n constructor(\n items: FeedItem[],\n private hydration: HydrationState,\n ) {\n items.forEach((item) => {\n if (!item.repost) {\n this.feedUris.add(item.post.uri)\n }\n })\n }\n\n ok(uri: AtUriString, loop = new Set<AtUriString>()) {\n // if we've already checked this uri, pull from the cache\n if (this.cache.has(uri)) {\n return this.cache.get(uri) ?? false\n }\n // loop detection\n if (loop.has(uri)) {\n this.cache.set(uri, false)\n return false\n } else {\n loop.add(uri)\n }\n // cache through the result\n const result = this._ok(uri, loop)\n this.cache.set(uri, result)\n return result\n }\n\n private _ok(uri: AtUriString, loop: Set<AtUriString>): boolean {\n // must be in the feed to be in a self-thread\n if (!this.feedUris.has(uri)) {\n return false\n }\n // must be hydratable to be part of self-thread\n const post = this.hydration.posts?.get(uri)\n if (!post) {\n return false\n }\n // root posts (no parent) are trivial case of self-thread\n const parentUri = getParentUri(post)\n if (parentUri === null) {\n return true\n }\n // recurse w/ cache: this post is in a self-thread if its parent is.\n return this.ok(parentUri, loop)\n }\n}\n\nfunction getParentUri(post: Post) {\n return post.record.reply?.parent.uri ?? null\n}\n"]}
1
+ {"version":3,"file":"getAuthorFeed.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/feed/getAuthorFeed.ts"],"names":[],"mappings":"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","sourcesContent":["import { mapDefined } from '@atproto/common'\nimport type { AtUriString } from '@atproto/lex'\nimport { InvalidRequestError, type Server } from '@atproto/xrpc-server'\nimport type { AppContext } from '../../../../context.js'\nimport type { DataPlaneClient } from '../../../../data-plane/index.js'\nimport type { Actor } from '../../../../hydration/actor.js'\nimport type { FeedItem, Post } from '../../../../hydration/feed.js'\nimport {\n type HydrateCtx,\n type HydrationState,\n type Hydrator,\n mergeStates,\n} from '../../../../hydration/hydrator.js'\nimport { parseString } from '../../../../hydration/util.js'\nimport { app } from '../../../../lexicons/index.js'\nimport { createPipeline } from '../../../../pipeline.js'\nimport { FeedType } from '../../../../proto/bsky_pb.js'\nimport { safePinnedPost, uriToDid } from '../../../../util/uris.js'\nimport type { Views } from '../../../../views/index.js'\nimport { clearlyBadCursor, fillPage, resHeaders } from '../../../util.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const getAuthorFeed = createPipeline(\n skeleton,\n hydration,\n noBlocksOrMutedReposts,\n presentation,\n )\n server.add(app.bsky.feed.getAuthorFeed, {\n auth: ctx.authVerifier.optionalStandardOrRole,\n handler: async ({ params, auth, req }) => {\n const { viewer, includeTakedowns, skipViewerBlocks } =\n ctx.authVerifier.parseCreds(auth)\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({\n xrpcEndpoint: app.bsky.feed.getAuthorFeed.$lxm,\n labelers,\n viewer,\n includeTakedowns,\n skipViewerBlocks,\n features: ctx.featureGatesClient.scope(\n ctx.featureGatesClient.parseUserContextFromHandler({ viewer, req }),\n ),\n })\n\n const result = await fillPage({\n cursor: params.cursor,\n limit: params.limit,\n fetch: ({ cursor, limit }) =>\n getAuthorFeed({ ...params, cursor, limit, hydrateCtx }, ctx),\n items: (r) => r.feed,\n })\n\n const repoRev = await ctx.hydrator.actor.getRepoRevSafe(viewer)\n\n return {\n encoding: 'application/json',\n body: result,\n headers: resHeaders({\n repoRev,\n labelers: hydrateCtx.labelers,\n }),\n }\n },\n })\n}\n\nconst FILTER_TO_FEED_TYPE = {\n posts_with_replies: undefined, // default: all posts, replies, and reposts\n posts_no_replies: FeedType.POSTS_NO_REPLIES,\n posts_with_media: FeedType.POSTS_WITH_MEDIA,\n posts_and_author_threads: FeedType.POSTS_AND_AUTHOR_THREADS,\n posts_with_video: FeedType.POSTS_WITH_VIDEO,\n}\n\nexport const skeleton = async (inputs: {\n ctx: Context\n params: Params\n}): Promise<Skeleton> => {\n const { ctx, params } = inputs\n const [did] = await ctx.hydrator.actor.getDids([params.actor])\n if (!did) {\n throw new InvalidRequestError('Profile not found')\n }\n const actors = await ctx.hydrator.actor.getActors([did], {\n includeTakedowns: params.hydrateCtx.includeTakedowns,\n skipCacheForDids: params.hydrateCtx.skipCacheForViewer,\n })\n const actor = actors.get(did)\n if (!actor) {\n throw new InvalidRequestError('Profile not found')\n }\n if (clearlyBadCursor(params.cursor)) {\n return { actor, filter: params.filter, items: [] }\n }\n\n const pinnedPost = safePinnedPost(actor.profile?.pinnedPost)\n const isFirstPageRequest = !params.cursor\n const shouldInsertPinnedPost =\n isFirstPageRequest &&\n params.includePins &&\n pinnedPost &&\n uriToDid(pinnedPost.uri) === actor.did\n\n const res = await ctx.dataplane.getAuthorFeed({\n actorDid: did,\n limit: params.limit,\n cursor: params.cursor,\n feedType: FILTER_TO_FEED_TYPE[params.filter],\n })\n\n let items: FeedItem[] = res.items.map((item) => ({\n post: { uri: item.uri as AtUriString, cid: item.cid || undefined },\n repost: item.repost\n ? { uri: item.repost as AtUriString, cid: item.repostCid || undefined }\n : undefined,\n }))\n\n if (shouldInsertPinnedPost && pinnedPost) {\n const pinnedItem = {\n post: {\n uri: pinnedPost.uri,\n cid: pinnedPost.cid,\n },\n authorPinned: true,\n }\n\n items = items.filter((item) => item.post.uri !== pinnedItem.post.uri)\n items.unshift(pinnedItem)\n }\n\n return {\n actor,\n filter: params.filter,\n items,\n cursor: parseString(res.cursor),\n }\n}\n\nconst hydration = async (inputs: {\n ctx: Context\n params: Params\n skeleton: Skeleton\n}): Promise<HydrationState> => {\n const { ctx, params, skeleton } = inputs\n const [feedPostState, profileViewerState] = await Promise.all([\n ctx.hydrator.hydrateFeedItems(skeleton.items, params.hydrateCtx, {\n knownLikers:\n !!params.hydrateCtx.viewer &&\n params.hydrateCtx.features.checkGate(\n params.hydrateCtx.features.Gate.KnownLikersFeedEnable,\n ),\n }),\n ctx.hydrator.hydrateProfileViewers([skeleton.actor.did], params.hydrateCtx),\n ])\n return mergeStates(feedPostState, profileViewerState)\n}\n\nconst noBlocksOrMutedReposts = (inputs: {\n ctx: Context\n skeleton: Skeleton\n hydration: HydrationState\n}): Skeleton => {\n const { ctx, skeleton, hydration } = inputs\n const relationship = hydration.profileViewers?.get(skeleton.actor.did)\n if (\n !hydration.ctx?.skipViewerBlocks &&\n relationship &&\n (relationship.blocking || ctx.views.blockingByList(relationship, hydration))\n ) {\n throw new InvalidRequestError(\n `Requester has blocked actor: ${skeleton.actor.did}`,\n 'BlockedActor',\n )\n }\n if (\n !hydration.ctx?.skipViewerBlocks &&\n relationship &&\n (relationship.blockedBy || ctx.views.blockedByList(relationship, hydration))\n ) {\n throw new InvalidRequestError(\n `Requester is blocked by actor: ${skeleton.actor.did}`,\n 'BlockedByActor',\n )\n }\n\n const checkBlocksAndMutes = (item: FeedItem) => {\n const bam = ctx.views.feedItemBlocksAndMutes(item, hydration)\n return (\n !bam.authorBlocked &&\n !bam.originatorBlocked &&\n (!bam.authorMuted || bam.originatorMuted) // repost of muted content\n )\n }\n\n if (skeleton.filter === 'posts_and_author_threads') {\n // ensure replies are only included if the feed contains all\n // replies up to the thread root (i.e. a complete self-thread.)\n const selfThread = new SelfThreadTracker(skeleton.items, hydration)\n skeleton.items = skeleton.items.filter((item) => {\n return (\n checkBlocksAndMutes(item) &&\n (item.repost || item.authorPinned || selfThread.ok(item.post.uri))\n )\n })\n } else {\n skeleton.items = skeleton.items.filter(checkBlocksAndMutes)\n }\n\n return skeleton\n}\n\nconst presentation = (inputs: {\n ctx: Context\n skeleton: Skeleton\n hydration: HydrationState\n}) => {\n const { ctx, skeleton, hydration } = inputs\n const feed = mapDefined(skeleton.items, (item) =>\n ctx.views.feedViewPost(item, hydration),\n )\n return { feed, cursor: skeleton.cursor }\n}\n\ntype Context = {\n hydrator: Hydrator\n views: Views\n dataplane: DataPlaneClient\n}\n\ntype Params = app.bsky.feed.getAuthorFeed.$Params & {\n hydrateCtx: HydrateCtx\n}\n\ntype Skeleton = {\n actor: Actor\n items: FeedItem[]\n filter: app.bsky.feed.getAuthorFeed.$Params['filter']\n cursor?: string\n}\n\nclass SelfThreadTracker {\n feedUris = new Set<AtUriString>()\n cache = new Map<AtUriString, boolean>()\n\n constructor(\n items: FeedItem[],\n private hydration: HydrationState,\n ) {\n items.forEach((item) => {\n if (!item.repost) {\n this.feedUris.add(item.post.uri)\n }\n })\n }\n\n ok(uri: AtUriString, loop = new Set<AtUriString>()) {\n // if we've already checked this uri, pull from the cache\n if (this.cache.has(uri)) {\n return this.cache.get(uri) ?? false\n }\n // loop detection\n if (loop.has(uri)) {\n this.cache.set(uri, false)\n return false\n } else {\n loop.add(uri)\n }\n // cache through the result\n const result = this._ok(uri, loop)\n this.cache.set(uri, result)\n return result\n }\n\n private _ok(uri: AtUriString, loop: Set<AtUriString>): boolean {\n // must be in the feed to be in a self-thread\n if (!this.feedUris.has(uri)) {\n return false\n }\n // must be hydratable to be part of self-thread\n const post = this.hydration.posts?.get(uri)\n if (!post) {\n return false\n }\n // root posts (no parent) are trivial case of self-thread\n const parentUri = getParentUri(post)\n if (parentUri === null) {\n return true\n }\n // recurse w/ cache: this post is in a self-thread if its parent is.\n return this.ok(parentUri, loop)\n }\n}\n\nfunction getParentUri(post: Post) {\n return post.record.reply?.parent.uri ?? null\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"getFeed.d.ts","sourceRoot":"","sources":["../../../../../src/api/app/bsky/feed/getFeed.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,SAAS,EAIf,MAAM,cAAc,CAAA;AAErB,OAAO,EACL,KAAK,OAAO,IAAI,UAAU,EAE1B,KAAK,MAAM,EAKZ,MAAM,sBAAsB,CAAA;AAC7B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AACzD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AASxD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAA;AAC7D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAA;AAanE,MAAM,CAAC,OAAO,WAAW,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,QAkEvD;AAuHD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,cAAc,QACpB,IAAI,CAAC,YAAY,EAAE,SAAS,GAAG,cAAc,CAAC,UAC3C;IACN,IAAI,EAAE,MAAM,CAAA;IACZ,cAAc,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,UAAU,EAAE;QACV,MAAM,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAA;QAC5B,QAAQ,EAAE,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC,CAAA;KAC7D,CAAA;CACF,KACA,MAAM,GAAG,SAgBX,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,qBAAqB,QAC3B,IAAI,CAAC,YAAY,EAAE,gBAAgB,GAAG,qBAAqB,CAAC,UACzD;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,KACvB,MAAM,GAAG,SACgE,CAAA;AAE5E;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,IAAI,CAAC,YAAY,EAAE,SAAS,GAAG,gBAAgB,GAAG,iBAAiB,CAAC,EACzE,MAAM,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,SAAS,CAAA;CAAE,GAC3C,MAAM,GAAG,SAAS,CAMpB;AA6JD,MAAM,MAAM,YAAY,GAAG;IACzB,SAAS,EAAE,gBAAgB,EAAE,CAAA;IAC7B,UAAU,CAAC,EAAE,UAAU,CAAA;IACvB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG,QAAQ,GAAG;IACxC,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,CAAA"}
1
+ {"version":3,"file":"getFeed.d.ts","sourceRoot":"","sources":["../../../../../src/api/app/bsky/feed/getFeed.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,SAAS,EAIf,MAAM,cAAc,CAAA;AAErB,OAAO,EACL,KAAK,OAAO,IAAI,UAAU,EAE1B,KAAK,MAAM,EAKZ,MAAM,sBAAsB,CAAA;AAC7B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AACzD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AASxD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAA;AAC7D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAA;AAanE,MAAM,CAAC,OAAO,WAAW,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,QAmEvD;AAuHD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,cAAc,QACpB,IAAI,CAAC,YAAY,EAAE,SAAS,GAAG,cAAc,CAAC,UAC3C;IACN,IAAI,EAAE,MAAM,CAAA;IACZ,cAAc,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,UAAU,EAAE;QACV,MAAM,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAA;QAC5B,QAAQ,EAAE,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC,CAAA;KAC7D,CAAA;CACF,KACA,MAAM,GAAG,SAgBX,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,qBAAqB,QAC3B,IAAI,CAAC,YAAY,EAAE,gBAAgB,GAAG,qBAAqB,CAAC,UACzD;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,KACvB,MAAM,GAAG,SACgE,CAAA;AAE5E;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,IAAI,CAAC,YAAY,EAAE,SAAS,GAAG,gBAAgB,GAAG,iBAAiB,CAAC,EACzE,MAAM,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,SAAS,CAAA;CAAE,GAC3C,MAAM,GAAG,SAAS,CAMpB;AA6JD,MAAM,MAAM,YAAY,GAAG;IACzB,SAAS,EAAE,gBAAgB,EAAE,CAAA;IAC7B,UAAU,CAAC,EAAE,UAAU,CAAA;IACvB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG,QAAQ,GAAG;IACxC,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,CAAA"}
@@ -24,6 +24,7 @@ export default function (server, ctx) {
24
24
  const stableDeviceId = req.header(ANALYTICS_HEADER_DEVICE_ID) ?? null;
25
25
  const labelers = ctx.reqLabelers(req);
26
26
  const hydrateCtx = await ctx.hydrator.createContext({
27
+ xrpcEndpoint: app.bsky.feed.getFeed.$lxm,
27
28
  labelers,
28
29
  viewer,
29
30
  features: ctx.featureGatesClient.scope(ctx.featureGatesClient.parseUserContextFromHandler({ viewer, req })),
@@ -1 +1 @@
1
- {"version":3,"file":"getFeed.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/feed/getFeed.ts"],"names":[],"mappings":"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","sourcesContent":["import { mapDefined, noUndefinedVals } from '@atproto/common'\nimport {\n type DidString,\n XrpcInvalidResponseError,\n XrpcResponseError,\n xrpcSafe,\n} from '@atproto/lex'\nimport { AtUri } from '@atproto/syntax'\nimport {\n type Headers as HeadersMap,\n InvalidRequestError,\n type Server,\n ServerTimer,\n UpstreamFailureError,\n XRPCError,\n serverTimingHeader,\n} from '@atproto/xrpc-server'\nimport type { ServerConfig } from '../../../../config.js'\nimport type { AppContext } from '../../../../context.js'\nimport {\n Code,\n getServiceEndpoint,\n isDataplaneError,\n unpackIdentityServices,\n} from '../../../../data-plane/index.js'\nimport { Gate } from '../../../../feature-gates/gates.js'\nimport { ANALYTICS_HEADER_DEVICE_ID } from '../../../../feature-gates/index.js'\nimport type { FeedItem } from '../../../../hydration/feed.js'\nimport type { HydrateCtx } from '../../../../hydration/hydrator.js'\nimport { app } from '../../../../lexicons/index.js'\nimport {\n type HydrationFnInput,\n type PresentationFnInput,\n type RulesFnInput,\n type SkeletonFnInput,\n createPipeline,\n} from '../../../../pipeline.js'\nimport type { GetIdentityByDidResponse } from '../../../../proto/bsky_pb.js'\nimport { getAtprotoPassthroughHeaders } from '../../../../util/headers.js'\nimport { BSKY_USER_AGENT, resHeaders } from '../../../util.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const getFeed = createPipeline(\n skeleton,\n hydration,\n noBlocksOrMutes,\n presentation,\n )\n server.add(app.bsky.feed.getFeed, {\n auth: ctx.authVerifier.standardOptionalParameterized({\n lxmCheck: (method) => {\n return (\n method === app.bsky.feed.getFeedSkeleton.$lxm ||\n method === app.bsky.feed.getFeed.$lxm\n )\n },\n skipAudCheck: true,\n }),\n handler: async ({ params, auth, req, signal }) => {\n const viewer = auth.credentials.iss\n const stableDeviceId = req.header(ANALYTICS_HEADER_DEVICE_ID) ?? null\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({\n labelers,\n viewer,\n features: ctx.featureGatesClient.scope(\n ctx.featureGatesClient.parseUserContextFromHandler({ viewer, req }),\n ),\n })\n const headers = noUndefinedVals({\n 'user-agent': BSKY_USER_AGENT,\n authorization: req.headers['authorization'],\n 'accept-language': req.headers['accept-language'],\n })\n const passthroughHeaders = getAtprotoPassthroughHeaders(req)\n // @NOTE feed cursors should not be affected by appview swap\n // Do not refill filtered pages. Overfetching from algorithmic feeds can\n // advance their state and prevent omitted items from appearing later.\n const result = await getFeed(\n {\n ...params,\n hydrateCtx,\n stableDeviceId,\n headers,\n passthroughHeaders,\n signal,\n },\n ctx,\n )\n const {\n timerSkele,\n timerHydr,\n resHeaders: feedResHeaders,\n ...body\n } = result\n\n return {\n encoding: 'application/json',\n body,\n headers: {\n ...feedResHeaders,\n ...resHeaders({ labelers: hydrateCtx.labelers }),\n 'server-timing': serverTimingHeader([timerSkele, timerHydr]),\n },\n }\n },\n })\n}\n\nconst skeleton = async (\n inputs: SkeletonFnInput<Context, Params>,\n): Promise<Skeleton> => {\n const { ctx, params } = inputs\n const timerSkele = new ServerTimer('skele').start()\n const {\n feedItems: algoItems,\n reqId,\n cursor,\n resHeaders,\n ...passthrough\n } = await skeletonFromFeedGen(ctx, params)\n\n return {\n cursor,\n items: algoItems,\n reqId,\n timerSkele: timerSkele.stop(),\n timerHydr: new ServerTimer('hydr').start(),\n resHeaders,\n passthrough,\n }\n}\n\nconst hydration = async (\n inputs: HydrationFnInput<Context, Params, Skeleton>,\n) => {\n const { ctx, params, skeleton } = inputs\n const timerHydr = new ServerTimer('hydr').start()\n const hydration = await ctx.hydrator.hydrateFeedItems(\n skeleton.items,\n params.hydrateCtx,\n {\n knownLikers:\n !!params.hydrateCtx.viewer &&\n params.hydrateCtx.features.checkGate(\n params.hydrateCtx.features.Gate.KnownLikersFeedEnable,\n ),\n },\n )\n skeleton.timerHydr = timerHydr.stop()\n return hydration\n}\n\nconst noBlocksOrMutes = (inputs: RulesFnInput<Context, Params, Skeleton>) => {\n const { ctx, skeleton, hydration } = inputs\n skeleton.items = skeleton.items.filter((item) => {\n const bam = ctx.views.feedItemBlocksAndMutes(item, hydration)\n return (\n !bam.authorBlocked &&\n !bam.authorMuted &&\n !bam.authorQuotepostMuted &&\n !bam.originatorBlocked &&\n !bam.originatorMuted &&\n !bam.originatorRepostMuted &&\n !bam.ancestorAuthorBlocked\n )\n })\n\n return skeleton\n}\n\nconst presentation = (\n inputs: PresentationFnInput<Context, Params, Skeleton>,\n) => {\n const { ctx, skeleton, hydration } = inputs\n const feed = mapDefined(skeleton.items, (item) => {\n const post = ctx.views.feedViewPost(item, hydration)\n if (!post) return\n return {\n ...post,\n feedContext: item.feedContext,\n }\n })\n return {\n feed: feed.map((fi) => ({ ...fi, reqId: skeleton.reqId })),\n cursor: skeleton.cursor,\n timerSkele: skeleton.timerSkele,\n timerHydr: skeleton.timerHydr,\n resHeaders: skeleton.resHeaders,\n ...skeleton.passthrough,\n }\n}\n\ntype Context = AppContext\n\ntype Params = app.bsky.feed.getFeed.$Params & {\n hydrateCtx: HydrateCtx\n stableDeviceId: string | null\n headers: HeadersMap\n passthroughHeaders: HeadersMap\n signal: AbortSignal\n}\n\ntype Skeleton = {\n items: AlgoResponseItem[]\n reqId?: string\n passthrough: Record<string, unknown> // pass through additional items in feedgen response\n resHeaders?: HeadersMap\n cursor?: string\n timerSkele: ServerTimer\n timerHydr: ServerTimer\n}\n\n/**\n * Per-feed rollout gates for the iris cutover, keyed by feed rkey.\n * Allowlisted feeds without a dedicated gate (whats-hot) use Gate.IrisFeed.\n */\nconst IRIS_FEED_RKEY_GATES: Record<string, Gate> = {\n 'with-friends': Gate.IrisFeedWithFriendsEnable,\n thevids: Gate.IrisFeedThevidsEnable,\n mutuals: Gate.IrisFeedMutualsEnable,\n 'bsky-team': Gate.IrisFeedBskyTeamEnable,\n 'best-of-follows': Gate.IrisFeedBestOfFollowsEnable,\n followpics: Gate.IrisFeedFollowpicsEnable,\n}\n\n/**\n * Iris' endpoint, when it should serve this request in place of the feed's\n * registered feed generator (seeemore).\n *\n * Logged-in viewers are routed by their per-feed gate. Logged-out viewers\n * have no DID, but the client sends a stable device id (stable_id) that\n * GrowthBook can bucket on, so they are routed by the dedicated\n * Gate.IrisFeedLoggedOutEnable gate instead. Requests without a stable\n * device id are never routed: the feature-gates context falls back to a\n * random id per request, which would flip backends between pages and send a\n * cursor to the backend that did not mint it.\n */\nexport const irisUrlForFeed = (\n cfg: Pick<ServerConfig, 'irisUrl' | 'irisFeedUris'>,\n params: {\n feed: string\n stableDeviceId: string | null\n hydrateCtx: {\n viewer: HydrateCtx['viewer']\n features: Pick<HydrateCtx['features'], 'Gate' | 'checkGate'>\n }\n },\n): string | undefined => {\n const { irisUrl } = cfg\n if (!irisUrl) return\n if (!cfg.irisFeedUris?.has(params.feed)) return\n if (!params.hydrateCtx.viewer) {\n if (!params.stableDeviceId) return\n return params.hydrateCtx.features.checkGate(Gate.IrisFeedLoggedOutEnable)\n ? irisUrl\n : undefined\n }\n const rkey = params.feed.split('/').at(-1)\n const gate = (rkey && IRIS_FEED_RKEY_GATES[rkey]) || Gate.IrisFeed\n if (!params.hydrateCtx.features.checkGate(gate)) {\n return\n }\n return irisUrl\n}\n\n/**\n * Iris staging's endpoint, when it should serve this request in place of the\n * feed's registered feed generator.\n */\nexport const irisStagingUrlForFeed = (\n cfg: Pick<ServerConfig, 'irisStagingUrl' | 'irisStagingFeedUris'>,\n params: { feed: string },\n): string | undefined =>\n cfg.irisStagingFeedUris?.has(params.feed) ? cfg.irisStagingUrl : undefined\n\n/**\n * Iris' local endpoint for configured trending feeds registered to Iris.\n */\nexport function irisUrlForTrendingFeed(\n cfg: Pick<ServerConfig, 'irisUrl' | 'irisServiceDid' | 'trendingFeedDid'>,\n params: { feed: string; feedDid: DidString },\n): string | undefined {\n const { irisUrl, irisServiceDid, trendingFeedDid } = cfg\n if (!irisUrl || !irisServiceDid || !trendingFeedDid) return\n if (params.feedDid !== irisServiceDid) return\n if (new AtUri(params.feed).host !== trendingFeedDid) return\n return irisUrl\n}\n\nconst resolveSkeletonEndpoint = async (\n ctx: Context,\n params: Params,\n): Promise<{ endpoint: string; feedDid?: DidString; trusted?: boolean }> => {\n const { feed } = params\n const irisUrl = irisUrlForFeed(ctx.cfg, params)\n if (irisUrl) {\n return {\n endpoint: irisUrl,\n feedDid: await getFeedGenDid(ctx, feed),\n trusted: true,\n }\n }\n\n const irisStagingUrl = irisStagingUrlForFeed(ctx.cfg, params)\n if (irisStagingUrl) {\n return {\n endpoint: irisStagingUrl,\n feedDid: await getFeedGenDid(ctx, feed),\n trusted: true,\n }\n }\n\n const feedDid = await getFeedGenDid(ctx, feed)\n if (!feedDid) {\n throw new InvalidRequestError('could not find feed')\n }\n\n const trendingIrisUrl = irisUrlForTrendingFeed(ctx.cfg, { feed, feedDid })\n if (trendingIrisUrl) {\n return { endpoint: trendingIrisUrl, feedDid, trusted: true }\n }\n\n let identity: GetIdentityByDidResponse\n try {\n identity = await ctx.dataplane.getIdentityByDid({ did: feedDid })\n } catch (err) {\n if (isDataplaneError(err, Code.NotFound)) {\n throw new InvalidRequestError(`could not resolve identity: ${feedDid}`)\n }\n throw err\n }\n\n const services = unpackIdentityServices(identity.services)\n const fgEndpoint = getServiceEndpoint(services, {\n id: 'bsky_fg',\n type: 'BskyFeedGenerator',\n })\n if (!fgEndpoint) {\n throw new InvalidRequestError(\n `invalid feed generator service details in did document: ${feedDid}`,\n )\n }\n\n return { endpoint: fgEndpoint, feedDid, trusted: false }\n}\n\nasync function getFeedGenDid(\n ctx: Context,\n feed: Params['feed'],\n): Promise<DidString | undefined> {\n const found = await ctx.hydrator.feed.getFeedGens([feed], true)\n return found.get(feed)?.record.did\n}\n\nconst skeletonFromFeedGen = async (\n ctx: Context,\n params: Params,\n): Promise<AlgoResponse> => {\n const { headers, passthroughHeaders } = params\n const { endpoint, feedDid, trusted } = await resolveSkeletonEndpoint(\n ctx,\n params,\n )\n const requestHeaders = noUndefinedVals({\n ...headers,\n ...(feedDid && ctx.cfg.bskyFeedgenDids.has(feedDid)\n ? passthroughHeaders\n : {}),\n })\n\n // @TODO currently passthrough auth headers from pds\n // Configured endpoints (iris) are ours. The DID-document path is resolved from\n // another account's record, so only that one goes through the guarded fetch.\n const result = await xrpcSafe(\n trusted ? endpoint : { service: endpoint, fetch: ctx.federatedFetch },\n app.bsky.feed.getFeedSkeleton,\n {\n strictResponseProcessing: false,\n signal: AbortSignal.any([\n params.signal,\n AbortSignal.timeout(ctx.cfg.feedGenSkeletonTimeout),\n ]),\n headers: requestHeaders,\n params: {\n feed: params.feed,\n // The feedgen is not guaranteed to honor the limit, but we try it.\n limit: params.limit,\n cursor: params.cursor,\n },\n },\n )\n\n if (!result.success) {\n const cause = result.reason\n\n // Pass through structurally valid XRPC error response (4xx/5xx), such as\n // auth errors\n if (cause instanceof XrpcResponseError) {\n const { status, body } = cause.toDownstreamError()\n throw new XRPCError(status, body.message, body.error, { cause })\n }\n\n // The response does not match the schema\n if (cause instanceof XrpcInvalidResponseError) {\n throw new UpstreamFailureError(\n 'feed provided an invalid response',\n 'InvalidFeedResponse',\n { cause },\n )\n }\n\n // Typically a network error.\n throw new UpstreamFailureError('feed unavailable', undefined, { cause })\n }\n\n const { feed: feedSkele, cursor, ...skele } = result.body\n const feedItems = feedSkele.slice(0, params.limit).map((item) => ({\n post: { uri: item.post },\n repost:\n item.reason != null &&\n app.bsky.feed.defs.skeletonReasonRepost.$isTypeOf(item.reason)\n ? { uri: item.reason.repost }\n : undefined,\n authorPinned:\n item.reason != null &&\n app.bsky.feed.defs.skeletonReasonPin.$isTypeOf(item.reason)\n ? true\n : undefined,\n feedContext: item.feedContext,\n }))\n\n const contentLang = result.headers.get('content-language')\n\n return {\n ...skele,\n resHeaders: contentLang ? { 'content-language': contentLang } : undefined,\n feedItems,\n // An empty feed-generator page ends pagination even if it includes a cursor.\n // Also prevent loops if the custom feed echoes the input cursor back.\n cursor:\n feedSkele.length === 0 || cursor === params.cursor ? undefined : cursor,\n }\n}\n\nexport type AlgoResponse = {\n feedItems: AlgoResponseItem[]\n resHeaders?: HeadersMap\n cursor?: string\n reqId?: string\n}\n\nexport type AlgoResponseItem = FeedItem & {\n feedContext?: string\n}\n"]}
1
+ {"version":3,"file":"getFeed.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/feed/getFeed.ts"],"names":[],"mappings":"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","sourcesContent":["import { mapDefined, noUndefinedVals } from '@atproto/common'\nimport {\n type DidString,\n XrpcInvalidResponseError,\n XrpcResponseError,\n xrpcSafe,\n} from '@atproto/lex'\nimport { AtUri } from '@atproto/syntax'\nimport {\n type Headers as HeadersMap,\n InvalidRequestError,\n type Server,\n ServerTimer,\n UpstreamFailureError,\n XRPCError,\n serverTimingHeader,\n} from '@atproto/xrpc-server'\nimport type { ServerConfig } from '../../../../config.js'\nimport type { AppContext } from '../../../../context.js'\nimport {\n Code,\n getServiceEndpoint,\n isDataplaneError,\n unpackIdentityServices,\n} from '../../../../data-plane/index.js'\nimport { Gate } from '../../../../feature-gates/gates.js'\nimport { ANALYTICS_HEADER_DEVICE_ID } from '../../../../feature-gates/index.js'\nimport type { FeedItem } from '../../../../hydration/feed.js'\nimport type { HydrateCtx } from '../../../../hydration/hydrator.js'\nimport { app } from '../../../../lexicons/index.js'\nimport {\n type HydrationFnInput,\n type PresentationFnInput,\n type RulesFnInput,\n type SkeletonFnInput,\n createPipeline,\n} from '../../../../pipeline.js'\nimport type { GetIdentityByDidResponse } from '../../../../proto/bsky_pb.js'\nimport { getAtprotoPassthroughHeaders } from '../../../../util/headers.js'\nimport { BSKY_USER_AGENT, resHeaders } from '../../../util.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const getFeed = createPipeline(\n skeleton,\n hydration,\n noBlocksOrMutes,\n presentation,\n )\n server.add(app.bsky.feed.getFeed, {\n auth: ctx.authVerifier.standardOptionalParameterized({\n lxmCheck: (method) => {\n return (\n method === app.bsky.feed.getFeedSkeleton.$lxm ||\n method === app.bsky.feed.getFeed.$lxm\n )\n },\n skipAudCheck: true,\n }),\n handler: async ({ params, auth, req, signal }) => {\n const viewer = auth.credentials.iss\n const stableDeviceId = req.header(ANALYTICS_HEADER_DEVICE_ID) ?? null\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({\n xrpcEndpoint: app.bsky.feed.getFeed.$lxm,\n labelers,\n viewer,\n features: ctx.featureGatesClient.scope(\n ctx.featureGatesClient.parseUserContextFromHandler({ viewer, req }),\n ),\n })\n const headers = noUndefinedVals({\n 'user-agent': BSKY_USER_AGENT,\n authorization: req.headers['authorization'],\n 'accept-language': req.headers['accept-language'],\n })\n const passthroughHeaders = getAtprotoPassthroughHeaders(req)\n // @NOTE feed cursors should not be affected by appview swap\n // Do not refill filtered pages. Overfetching from algorithmic feeds can\n // advance their state and prevent omitted items from appearing later.\n const result = await getFeed(\n {\n ...params,\n hydrateCtx,\n stableDeviceId,\n headers,\n passthroughHeaders,\n signal,\n },\n ctx,\n )\n const {\n timerSkele,\n timerHydr,\n resHeaders: feedResHeaders,\n ...body\n } = result\n\n return {\n encoding: 'application/json',\n body,\n headers: {\n ...feedResHeaders,\n ...resHeaders({ labelers: hydrateCtx.labelers }),\n 'server-timing': serverTimingHeader([timerSkele, timerHydr]),\n },\n }\n },\n })\n}\n\nconst skeleton = async (\n inputs: SkeletonFnInput<Context, Params>,\n): Promise<Skeleton> => {\n const { ctx, params } = inputs\n const timerSkele = new ServerTimer('skele').start()\n const {\n feedItems: algoItems,\n reqId,\n cursor,\n resHeaders,\n ...passthrough\n } = await skeletonFromFeedGen(ctx, params)\n\n return {\n cursor,\n items: algoItems,\n reqId,\n timerSkele: timerSkele.stop(),\n timerHydr: new ServerTimer('hydr').start(),\n resHeaders,\n passthrough,\n }\n}\n\nconst hydration = async (\n inputs: HydrationFnInput<Context, Params, Skeleton>,\n) => {\n const { ctx, params, skeleton } = inputs\n const timerHydr = new ServerTimer('hydr').start()\n const hydration = await ctx.hydrator.hydrateFeedItems(\n skeleton.items,\n params.hydrateCtx,\n {\n knownLikers:\n !!params.hydrateCtx.viewer &&\n params.hydrateCtx.features.checkGate(\n params.hydrateCtx.features.Gate.KnownLikersFeedEnable,\n ),\n },\n )\n skeleton.timerHydr = timerHydr.stop()\n return hydration\n}\n\nconst noBlocksOrMutes = (inputs: RulesFnInput<Context, Params, Skeleton>) => {\n const { ctx, skeleton, hydration } = inputs\n skeleton.items = skeleton.items.filter((item) => {\n const bam = ctx.views.feedItemBlocksAndMutes(item, hydration)\n return (\n !bam.authorBlocked &&\n !bam.authorMuted &&\n !bam.authorQuotepostMuted &&\n !bam.originatorBlocked &&\n !bam.originatorMuted &&\n !bam.originatorRepostMuted &&\n !bam.ancestorAuthorBlocked\n )\n })\n\n return skeleton\n}\n\nconst presentation = (\n inputs: PresentationFnInput<Context, Params, Skeleton>,\n) => {\n const { ctx, skeleton, hydration } = inputs\n const feed = mapDefined(skeleton.items, (item) => {\n const post = ctx.views.feedViewPost(item, hydration)\n if (!post) return\n return {\n ...post,\n feedContext: item.feedContext,\n }\n })\n return {\n feed: feed.map((fi) => ({ ...fi, reqId: skeleton.reqId })),\n cursor: skeleton.cursor,\n timerSkele: skeleton.timerSkele,\n timerHydr: skeleton.timerHydr,\n resHeaders: skeleton.resHeaders,\n ...skeleton.passthrough,\n }\n}\n\ntype Context = AppContext\n\ntype Params = app.bsky.feed.getFeed.$Params & {\n hydrateCtx: HydrateCtx\n stableDeviceId: string | null\n headers: HeadersMap\n passthroughHeaders: HeadersMap\n signal: AbortSignal\n}\n\ntype Skeleton = {\n items: AlgoResponseItem[]\n reqId?: string\n passthrough: Record<string, unknown> // pass through additional items in feedgen response\n resHeaders?: HeadersMap\n cursor?: string\n timerSkele: ServerTimer\n timerHydr: ServerTimer\n}\n\n/**\n * Per-feed rollout gates for the iris cutover, keyed by feed rkey.\n * Allowlisted feeds without a dedicated gate (whats-hot) use Gate.IrisFeed.\n */\nconst IRIS_FEED_RKEY_GATES: Record<string, Gate> = {\n 'with-friends': Gate.IrisFeedWithFriendsEnable,\n thevids: Gate.IrisFeedThevidsEnable,\n mutuals: Gate.IrisFeedMutualsEnable,\n 'bsky-team': Gate.IrisFeedBskyTeamEnable,\n 'best-of-follows': Gate.IrisFeedBestOfFollowsEnable,\n followpics: Gate.IrisFeedFollowpicsEnable,\n}\n\n/**\n * Iris' endpoint, when it should serve this request in place of the feed's\n * registered feed generator (seeemore).\n *\n * Logged-in viewers are routed by their per-feed gate. Logged-out viewers\n * have no DID, but the client sends a stable device id (stable_id) that\n * GrowthBook can bucket on, so they are routed by the dedicated\n * Gate.IrisFeedLoggedOutEnable gate instead. Requests without a stable\n * device id are never routed: the feature-gates context falls back to a\n * random id per request, which would flip backends between pages and send a\n * cursor to the backend that did not mint it.\n */\nexport const irisUrlForFeed = (\n cfg: Pick<ServerConfig, 'irisUrl' | 'irisFeedUris'>,\n params: {\n feed: string\n stableDeviceId: string | null\n hydrateCtx: {\n viewer: HydrateCtx['viewer']\n features: Pick<HydrateCtx['features'], 'Gate' | 'checkGate'>\n }\n },\n): string | undefined => {\n const { irisUrl } = cfg\n if (!irisUrl) return\n if (!cfg.irisFeedUris?.has(params.feed)) return\n if (!params.hydrateCtx.viewer) {\n if (!params.stableDeviceId) return\n return params.hydrateCtx.features.checkGate(Gate.IrisFeedLoggedOutEnable)\n ? irisUrl\n : undefined\n }\n const rkey = params.feed.split('/').at(-1)\n const gate = (rkey && IRIS_FEED_RKEY_GATES[rkey]) || Gate.IrisFeed\n if (!params.hydrateCtx.features.checkGate(gate)) {\n return\n }\n return irisUrl\n}\n\n/**\n * Iris staging's endpoint, when it should serve this request in place of the\n * feed's registered feed generator.\n */\nexport const irisStagingUrlForFeed = (\n cfg: Pick<ServerConfig, 'irisStagingUrl' | 'irisStagingFeedUris'>,\n params: { feed: string },\n): string | undefined =>\n cfg.irisStagingFeedUris?.has(params.feed) ? cfg.irisStagingUrl : undefined\n\n/**\n * Iris' local endpoint for configured trending feeds registered to Iris.\n */\nexport function irisUrlForTrendingFeed(\n cfg: Pick<ServerConfig, 'irisUrl' | 'irisServiceDid' | 'trendingFeedDid'>,\n params: { feed: string; feedDid: DidString },\n): string | undefined {\n const { irisUrl, irisServiceDid, trendingFeedDid } = cfg\n if (!irisUrl || !irisServiceDid || !trendingFeedDid) return\n if (params.feedDid !== irisServiceDid) return\n if (new AtUri(params.feed).host !== trendingFeedDid) return\n return irisUrl\n}\n\nconst resolveSkeletonEndpoint = async (\n ctx: Context,\n params: Params,\n): Promise<{ endpoint: string; feedDid?: DidString; trusted?: boolean }> => {\n const { feed } = params\n const irisUrl = irisUrlForFeed(ctx.cfg, params)\n if (irisUrl) {\n return {\n endpoint: irisUrl,\n feedDid: await getFeedGenDid(ctx, feed),\n trusted: true,\n }\n }\n\n const irisStagingUrl = irisStagingUrlForFeed(ctx.cfg, params)\n if (irisStagingUrl) {\n return {\n endpoint: irisStagingUrl,\n feedDid: await getFeedGenDid(ctx, feed),\n trusted: true,\n }\n }\n\n const feedDid = await getFeedGenDid(ctx, feed)\n if (!feedDid) {\n throw new InvalidRequestError('could not find feed')\n }\n\n const trendingIrisUrl = irisUrlForTrendingFeed(ctx.cfg, { feed, feedDid })\n if (trendingIrisUrl) {\n return { endpoint: trendingIrisUrl, feedDid, trusted: true }\n }\n\n let identity: GetIdentityByDidResponse\n try {\n identity = await ctx.dataplane.getIdentityByDid({ did: feedDid })\n } catch (err) {\n if (isDataplaneError(err, Code.NotFound)) {\n throw new InvalidRequestError(`could not resolve identity: ${feedDid}`)\n }\n throw err\n }\n\n const services = unpackIdentityServices(identity.services)\n const fgEndpoint = getServiceEndpoint(services, {\n id: 'bsky_fg',\n type: 'BskyFeedGenerator',\n })\n if (!fgEndpoint) {\n throw new InvalidRequestError(\n `invalid feed generator service details in did document: ${feedDid}`,\n )\n }\n\n return { endpoint: fgEndpoint, feedDid, trusted: false }\n}\n\nasync function getFeedGenDid(\n ctx: Context,\n feed: Params['feed'],\n): Promise<DidString | undefined> {\n const found = await ctx.hydrator.feed.getFeedGens([feed], true)\n return found.get(feed)?.record.did\n}\n\nconst skeletonFromFeedGen = async (\n ctx: Context,\n params: Params,\n): Promise<AlgoResponse> => {\n const { headers, passthroughHeaders } = params\n const { endpoint, feedDid, trusted } = await resolveSkeletonEndpoint(\n ctx,\n params,\n )\n const requestHeaders = noUndefinedVals({\n ...headers,\n ...(feedDid && ctx.cfg.bskyFeedgenDids.has(feedDid)\n ? passthroughHeaders\n : {}),\n })\n\n // @TODO currently passthrough auth headers from pds\n // Configured endpoints (iris) are ours. The DID-document path is resolved from\n // another account's record, so only that one goes through the guarded fetch.\n const result = await xrpcSafe(\n trusted ? endpoint : { service: endpoint, fetch: ctx.federatedFetch },\n app.bsky.feed.getFeedSkeleton,\n {\n strictResponseProcessing: false,\n signal: AbortSignal.any([\n params.signal,\n AbortSignal.timeout(ctx.cfg.feedGenSkeletonTimeout),\n ]),\n headers: requestHeaders,\n params: {\n feed: params.feed,\n // The feedgen is not guaranteed to honor the limit, but we try it.\n limit: params.limit,\n cursor: params.cursor,\n },\n },\n )\n\n if (!result.success) {\n const cause = result.reason\n\n // Pass through structurally valid XRPC error response (4xx/5xx), such as\n // auth errors\n if (cause instanceof XrpcResponseError) {\n const { status, body } = cause.toDownstreamError()\n throw new XRPCError(status, body.message, body.error, { cause })\n }\n\n // The response does not match the schema\n if (cause instanceof XrpcInvalidResponseError) {\n throw new UpstreamFailureError(\n 'feed provided an invalid response',\n 'InvalidFeedResponse',\n { cause },\n )\n }\n\n // Typically a network error.\n throw new UpstreamFailureError('feed unavailable', undefined, { cause })\n }\n\n const { feed: feedSkele, cursor, ...skele } = result.body\n const feedItems = feedSkele.slice(0, params.limit).map((item) => ({\n post: { uri: item.post },\n repost:\n item.reason != null &&\n app.bsky.feed.defs.skeletonReasonRepost.$isTypeOf(item.reason)\n ? { uri: item.reason.repost }\n : undefined,\n authorPinned:\n item.reason != null &&\n app.bsky.feed.defs.skeletonReasonPin.$isTypeOf(item.reason)\n ? true\n : undefined,\n feedContext: item.feedContext,\n }))\n\n const contentLang = result.headers.get('content-language')\n\n return {\n ...skele,\n resHeaders: contentLang ? { 'content-language': contentLang } : undefined,\n feedItems,\n // An empty feed-generator page ends pagination even if it includes a cursor.\n // Also prevent loops if the custom feed echoes the input cursor back.\n cursor:\n feedSkele.length === 0 || cursor === params.cursor ? undefined : cursor,\n }\n}\n\nexport type AlgoResponse = {\n feedItems: AlgoResponseItem[]\n resHeaders?: HeadersMap\n cursor?: string\n reqId?: string\n}\n\nexport type AlgoResponseItem = FeedItem & {\n feedContext?: string\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"getFeedGenerator.d.ts","sourceRoot":"","sources":["../../../../../src/api/app/bsky/feed/getFeedGenerator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,MAAM,EAAE,MAAM,sBAAsB,CAAA;AACvE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAWxD,MAAM,CAAC,OAAO,WAAW,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,QAuDvD"}
1
+ {"version":3,"file":"getFeedGenerator.d.ts","sourceRoot":"","sources":["../../../../../src/api/app/bsky/feed/getFeedGenerator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,MAAM,EAAE,MAAM,sBAAsB,CAAA;AACvE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAWxD,MAAM,CAAC,OAAO,WAAW,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,QA2DvD"}
@@ -9,7 +9,11 @@ export default function (server, ctx) {
9
9
  const { feed } = params;
10
10
  const viewer = auth.credentials.iss;
11
11
  const labelers = ctx.reqLabelers(req);
12
- const hydrateCtx = await ctx.hydrator.createContext({ labelers, viewer });
12
+ const hydrateCtx = await ctx.hydrator.createContext({
13
+ labelers,
14
+ viewer,
15
+ xrpcEndpoint: app.bsky.feed.getFeedGenerator.$lxm,
16
+ });
13
17
  const hydration = await ctx.hydrator.hydrateFeedGens([feed], hydrateCtx);
14
18
  const feedInfo = hydration.feedgens?.get(feed);
15
19
  if (!feedInfo) {
@@ -1 +1 @@
1
- {"version":3,"file":"getFeedGenerator.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/feed/getFeedGenerator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAe,MAAM,sBAAsB,CAAA;AAEvE,OAAO,EACL,IAAI,EACJ,kBAAkB,EAClB,gBAAgB,EAChB,sBAAsB,GACvB,MAAM,iCAAiC,CAAA;AACxC,OAAO,EAAE,GAAG,EAAE,MAAM,+BAA+B,CAAA;AAEnD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAE7C,MAAM,CAAC,OAAO,WAAW,MAAc,EAAE,GAAe;IACtD,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE;QACzC,IAAI,EAAE,GAAG,CAAC,YAAY,CAAC,gBAAgB;QACvC,OAAO,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE;YACvC,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,CAAA;YACvB,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAA;YACnC,MAAM,QAAQ,GAAG,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAA;YACrC,MAAM,UAAU,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAA;YACzE,MAAM,SAAS,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,EAAE,UAAU,CAAC,CAAA;YACxE,MAAM,QAAQ,GAAG,SAAS,CAAC,QAAQ,EAAE,GAAG,CAAC,IAAI,CAAC,CAAA;YAC9C,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,MAAM,IAAI,mBAAmB,CAAC,qBAAqB,CAAC,CAAA;YACtD,CAAC;YAED,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAA;YACnC,IAAI,QAAkC,CAAA;YACtC,IAAI,CAAC;gBACH,QAAQ,GAAG,MAAM,GAAG,CAAC,SAAS,CAAC,gBAAgB,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CAAA;YACnE,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,IAAI,gBAAgB,CAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;oBACzC,MAAM,IAAI,mBAAmB,CAC3B,+BAA+B,OAAO,EAAE,CACzC,CAAA;gBACH,CAAC;gBACD,MAAM,GAAG,CAAA;YACX,CAAC;YAED,MAAM,QAAQ,GAAG,sBAAsB,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAA;YAC1D,MAAM,UAAU,GAAG,kBAAkB,CAAC,QAAQ,EAAE;gBAC9C,EAAE,EAAE,SAAS;gBACb,IAAI,EAAE,mBAAmB;aAC1B,CAAC,CAAA;YACF,IAAI,CAAC,UAAU,EAAE,CAAC;gBAChB,MAAM,IAAI,mBAAmB,CAC3B,2DAA2D,OAAO,EAAE,CACrE,CAAA;YACH,CAAC;YAED,MAAM,QAAQ,GAAG,GAAG,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,EAAE,SAAS,CAAC,CAAA;YACzD,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,MAAM,IAAI,mBAAmB,CAAC,qBAAqB,CAAC,CAAA;YACtD,CAAC;YAED,OAAO;gBACL,QAAQ,EAAE,kBAAkB;gBAC5B,IAAI,EAAE;oBACJ,IAAI,EAAE,QAAQ;oBACd,kGAAkG;oBAClG,QAAQ,EAAE,IAAI;oBACd,OAAO,EAAE,IAAI;iBACd;gBACD,OAAO,EAAE,UAAU,CAAC,EAAE,QAAQ,EAAE,UAAU,CAAC,QAAQ,EAAE,CAAC;aACvD,CAAA;QACH,CAAC;KACF,CAAC,CAAA;AACJ,CAAC","sourcesContent":["import { InvalidRequestError, type Server } from '@atproto/xrpc-server'\nimport type { AppContext } from '../../../../context.js'\nimport {\n Code,\n getServiceEndpoint,\n isDataplaneError,\n unpackIdentityServices,\n} from '../../../../data-plane/index.js'\nimport { app } from '../../../../lexicons/index.js'\nimport type { GetIdentityByDidResponse } from '../../../../proto/bsky_pb.js'\nimport { resHeaders } from '../../../util.js'\n\nexport default function (server: Server, ctx: AppContext) {\n server.add(app.bsky.feed.getFeedGenerator, {\n auth: ctx.authVerifier.standardOptional,\n handler: async ({ params, auth, req }) => {\n const { feed } = params\n const viewer = auth.credentials.iss\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({ labelers, viewer })\n const hydration = await ctx.hydrator.hydrateFeedGens([feed], hydrateCtx)\n const feedInfo = hydration.feedgens?.get(feed)\n if (!feedInfo) {\n throw new InvalidRequestError('could not find feed')\n }\n\n const feedDid = feedInfo.record.did\n let identity: GetIdentityByDidResponse\n try {\n identity = await ctx.dataplane.getIdentityByDid({ did: feedDid })\n } catch (err) {\n if (isDataplaneError(err, Code.NotFound)) {\n throw new InvalidRequestError(\n `could not resolve identity: ${feedDid}`,\n )\n }\n throw err\n }\n\n const services = unpackIdentityServices(identity.services)\n const fgEndpoint = getServiceEndpoint(services, {\n id: 'bsky_fg',\n type: 'BskyFeedGenerator',\n })\n if (!fgEndpoint) {\n throw new InvalidRequestError(\n `invalid feed generator service details in did document: ${feedDid}`,\n )\n }\n\n const feedView = ctx.views.feedGenerator(feed, hydration)\n if (!feedView) {\n throw new InvalidRequestError('could not find feed')\n }\n\n return {\n encoding: 'application/json',\n body: {\n view: feedView,\n // @TODO temporarily hard-coding to true while external feedgens catch-up on describeFeedGenerator\n isOnline: true,\n isValid: true,\n },\n headers: resHeaders({ labelers: hydrateCtx.labelers }),\n }\n },\n })\n}\n"]}
1
+ {"version":3,"file":"getFeedGenerator.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/feed/getFeedGenerator.ts"],"names":[],"mappings":"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","sourcesContent":["import { InvalidRequestError, type Server } from '@atproto/xrpc-server'\nimport type { AppContext } from '../../../../context.js'\nimport {\n Code,\n getServiceEndpoint,\n isDataplaneError,\n unpackIdentityServices,\n} from '../../../../data-plane/index.js'\nimport { app } from '../../../../lexicons/index.js'\nimport type { GetIdentityByDidResponse } from '../../../../proto/bsky_pb.js'\nimport { resHeaders } from '../../../util.js'\n\nexport default function (server: Server, ctx: AppContext) {\n server.add(app.bsky.feed.getFeedGenerator, {\n auth: ctx.authVerifier.standardOptional,\n handler: async ({ params, auth, req }) => {\n const { feed } = params\n const viewer = auth.credentials.iss\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({\n labelers,\n viewer,\n xrpcEndpoint: app.bsky.feed.getFeedGenerator.$lxm,\n })\n const hydration = await ctx.hydrator.hydrateFeedGens([feed], hydrateCtx)\n const feedInfo = hydration.feedgens?.get(feed)\n if (!feedInfo) {\n throw new InvalidRequestError('could not find feed')\n }\n\n const feedDid = feedInfo.record.did\n let identity: GetIdentityByDidResponse\n try {\n identity = await ctx.dataplane.getIdentityByDid({ did: feedDid })\n } catch (err) {\n if (isDataplaneError(err, Code.NotFound)) {\n throw new InvalidRequestError(\n `could not resolve identity: ${feedDid}`,\n )\n }\n throw err\n }\n\n const services = unpackIdentityServices(identity.services)\n const fgEndpoint = getServiceEndpoint(services, {\n id: 'bsky_fg',\n type: 'BskyFeedGenerator',\n })\n if (!fgEndpoint) {\n throw new InvalidRequestError(\n `invalid feed generator service details in did document: ${feedDid}`,\n )\n }\n\n const feedView = ctx.views.feedGenerator(feed, hydration)\n if (!feedView) {\n throw new InvalidRequestError('could not find feed')\n }\n\n return {\n encoding: 'application/json',\n body: {\n view: feedView,\n // @TODO temporarily hard-coding to true while external feedgens catch-up on describeFeedGenerator\n isOnline: true,\n isValid: true,\n },\n headers: resHeaders({ labelers: hydrateCtx.labelers }),\n }\n },\n })\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"getFeedGenerators.d.ts","sourceRoot":"","sources":["../../../../../src/api/app/bsky/feed/getFeedGenerators.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAA;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAWxD,MAAM,CAAC,OAAO,WAAW,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,QA0BvD"}
1
+ {"version":3,"file":"getFeedGenerators.d.ts","sourceRoot":"","sources":["../../../../../src/api/app/bsky/feed/getFeedGenerators.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAA;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAWxD,MAAM,CAAC,OAAO,WAAW,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,QA8BvD"}
@@ -14,7 +14,11 @@ export default function (server, ctx) {
14
14
  handler: async ({ params, auth, req }) => {
15
15
  const viewer = auth.credentials.iss;
16
16
  const labelers = ctx.reqLabelers(req);
17
- const hydrateCtx = await ctx.hydrator.createContext({ labelers, viewer });
17
+ const hydrateCtx = await ctx.hydrator.createContext({
18
+ labelers,
19
+ viewer,
20
+ xrpcEndpoint: app.bsky.feed.getFeedGenerators.$lxm,
21
+ });
18
22
  const view = await getFeedGenerators({ ...params, hydrateCtx }, ctx);
19
23
  return {
20
24
  encoding: 'application/json',
@@ -1 +1 @@
1
- {"version":3,"file":"getFeedGenerators.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/feed/getFeedGenerators.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAS5C,OAAO,EAAE,GAAG,EAAE,MAAM,+BAA+B,CAAA;AACnD,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAA;AAEjE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAE7C,MAAM,CAAC,OAAO,WAAW,MAAc,EAAE,GAAe;IACtD,MAAM,iBAAiB,GAAG,cAAc,CACtC,QAAQ,EACR,SAAS,EACT,OAAO,EACP,YAAY,CACb,CAAA;IACD,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE;QAC1C,IAAI,EAAE,GAAG,CAAC,YAAY,CAAC,gBAAgB;QACvC,IAAI,EAAE;YACJ,wEAAwE;YACxE,gHAAgH;YAChH,gBAAgB,EAAE,IAAI;SACvB;QACD,OAAO,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE;YACvC,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAA;YACnC,MAAM,QAAQ,GAAG,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAA;YACrC,MAAM,UAAU,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAA;YACzE,MAAM,IAAI,GAAG,MAAM,iBAAiB,CAAC,EAAE,GAAG,MAAM,EAAE,UAAU,EAAE,EAAE,GAAG,CAAC,CAAA;YACpE,OAAO;gBACL,QAAQ,EAAE,kBAAkB;gBAC5B,IAAI,EAAE,IAAI;gBACV,OAAO,EAAE,UAAU,CAAC,EAAE,QAAQ,EAAE,UAAU,CAAC,QAAQ,EAAE,CAAC;aACvD,CAAA;QACH,CAAC;KACF,CAAC,CAAA;AACJ,CAAC;AAED,MAAM,QAAQ,GAAG,KAAK,EAAE,MAA0B,EAAqB,EAAE;IACvE,OAAO;QACL,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,KAAK;KAC9B,CAAA;AACH,CAAC,CAAA;AAED,MAAM,SAAS,GAAG,KAAK,EAAE,MAIxB,EAAE,EAAE;IACH,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAA;IACxC,OAAO,MAAM,GAAG,CAAC,QAAQ,CAAC,eAAe,CACvC,QAAQ,CAAC,QAAQ,EACjB,MAAM,CAAC,UAAU,CAClB,CAAA;AACH,CAAC,CAAA;AAED,MAAM,YAAY,GAAG,CAAC,MAIrB,EAAE,EAAE;IACH,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,MAAM,CAAA;IAC3C,MAAM,KAAK,GAAG,UAAU,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,EAAE,CAClD,GAAG,CAAC,KAAK,CAAC,aAAa,CAAC,GAAG,EAAE,SAAS,CAAC,CACxC,CAAA;IACD,OAAO;QACL,KAAK;KACN,CAAA;AACH,CAAC,CAAA","sourcesContent":["import { mapDefined } from '@atproto/common'\nimport type { AtUriString } from '@atproto/syntax'\nimport type { Server } from '@atproto/xrpc-server'\nimport type { AppContext } from '../../../../context.js'\nimport type {\n HydrateCtx,\n HydrationState,\n Hydrator,\n} from '../../../../hydration/hydrator.js'\nimport { app } from '../../../../lexicons/index.js'\nimport { createPipeline, noRules } from '../../../../pipeline.js'\nimport type { Views } from '../../../../views/index.js'\nimport { resHeaders } from '../../../util.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const getFeedGenerators = createPipeline(\n skeleton,\n hydration,\n noRules,\n presentation,\n )\n server.add(app.bsky.feed.getFeedGenerators, {\n auth: ctx.authVerifier.standardOptional,\n opts: {\n // @TODO remove after grace period has passed, behavior is non-standard.\n // temporarily added for compat w/ previous version of xrpc-server to avoid breakage of a few specified parties.\n paramsParseLoose: true,\n },\n handler: async ({ params, auth, req }) => {\n const viewer = auth.credentials.iss\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({ labelers, viewer })\n const view = await getFeedGenerators({ ...params, hydrateCtx }, ctx)\n return {\n encoding: 'application/json',\n body: view,\n headers: resHeaders({ labelers: hydrateCtx.labelers }),\n }\n },\n })\n}\n\nconst skeleton = async (inputs: { params: Params }): Promise<Skeleton> => {\n return {\n feedUris: inputs.params.feeds,\n }\n}\n\nconst hydration = async (inputs: {\n ctx: Context\n params: Params\n skeleton: Skeleton\n}) => {\n const { ctx, params, skeleton } = inputs\n return await ctx.hydrator.hydrateFeedGens(\n skeleton.feedUris,\n params.hydrateCtx,\n )\n}\n\nconst presentation = (inputs: {\n ctx: Context\n skeleton: Skeleton\n hydration: HydrationState\n}) => {\n const { ctx, skeleton, hydration } = inputs\n const feeds = mapDefined(skeleton.feedUris, (uri) =>\n ctx.views.feedGenerator(uri, hydration),\n )\n return {\n feeds,\n }\n}\n\ntype Context = {\n hydrator: Hydrator\n views: Views\n}\n\ntype Params = app.bsky.feed.getFeedGenerators.$Params & {\n hydrateCtx: HydrateCtx\n}\n\ntype Skeleton = {\n feedUris: AtUriString[]\n}\n"]}
1
+ {"version":3,"file":"getFeedGenerators.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/feed/getFeedGenerators.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAS5C,OAAO,EAAE,GAAG,EAAE,MAAM,+BAA+B,CAAA;AACnD,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAA;AAEjE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAE7C,MAAM,CAAC,OAAO,WAAW,MAAc,EAAE,GAAe;IACtD,MAAM,iBAAiB,GAAG,cAAc,CACtC,QAAQ,EACR,SAAS,EACT,OAAO,EACP,YAAY,CACb,CAAA;IACD,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE;QAC1C,IAAI,EAAE,GAAG,CAAC,YAAY,CAAC,gBAAgB;QACvC,IAAI,EAAE;YACJ,wEAAwE;YACxE,gHAAgH;YAChH,gBAAgB,EAAE,IAAI;SACvB;QACD,OAAO,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE;YACvC,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAA;YACnC,MAAM,QAAQ,GAAG,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAA;YACrC,MAAM,UAAU,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC,aAAa,CAAC;gBAClD,QAAQ;gBACR,MAAM;gBACN,YAAY,EAAE,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,IAAI;aACnD,CAAC,CAAA;YACF,MAAM,IAAI,GAAG,MAAM,iBAAiB,CAAC,EAAE,GAAG,MAAM,EAAE,UAAU,EAAE,EAAE,GAAG,CAAC,CAAA;YACpE,OAAO;gBACL,QAAQ,EAAE,kBAAkB;gBAC5B,IAAI,EAAE,IAAI;gBACV,OAAO,EAAE,UAAU,CAAC,EAAE,QAAQ,EAAE,UAAU,CAAC,QAAQ,EAAE,CAAC;aACvD,CAAA;QACH,CAAC;KACF,CAAC,CAAA;AACJ,CAAC;AAED,MAAM,QAAQ,GAAG,KAAK,EAAE,MAA0B,EAAqB,EAAE;IACvE,OAAO;QACL,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,KAAK;KAC9B,CAAA;AACH,CAAC,CAAA;AAED,MAAM,SAAS,GAAG,KAAK,EAAE,MAIxB,EAAE,EAAE;IACH,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAA;IACxC,OAAO,MAAM,GAAG,CAAC,QAAQ,CAAC,eAAe,CACvC,QAAQ,CAAC,QAAQ,EACjB,MAAM,CAAC,UAAU,CAClB,CAAA;AACH,CAAC,CAAA;AAED,MAAM,YAAY,GAAG,CAAC,MAIrB,EAAE,EAAE;IACH,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,MAAM,CAAA;IAC3C,MAAM,KAAK,GAAG,UAAU,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,EAAE,CAClD,GAAG,CAAC,KAAK,CAAC,aAAa,CAAC,GAAG,EAAE,SAAS,CAAC,CACxC,CAAA;IACD,OAAO;QACL,KAAK;KACN,CAAA;AACH,CAAC,CAAA","sourcesContent":["import { mapDefined } from '@atproto/common'\nimport type { AtUriString } from '@atproto/syntax'\nimport type { Server } from '@atproto/xrpc-server'\nimport type { AppContext } from '../../../../context.js'\nimport type {\n HydrateCtx,\n HydrationState,\n Hydrator,\n} from '../../../../hydration/hydrator.js'\nimport { app } from '../../../../lexicons/index.js'\nimport { createPipeline, noRules } from '../../../../pipeline.js'\nimport type { Views } from '../../../../views/index.js'\nimport { resHeaders } from '../../../util.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const getFeedGenerators = createPipeline(\n skeleton,\n hydration,\n noRules,\n presentation,\n )\n server.add(app.bsky.feed.getFeedGenerators, {\n auth: ctx.authVerifier.standardOptional,\n opts: {\n // @TODO remove after grace period has passed, behavior is non-standard.\n // temporarily added for compat w/ previous version of xrpc-server to avoid breakage of a few specified parties.\n paramsParseLoose: true,\n },\n handler: async ({ params, auth, req }) => {\n const viewer = auth.credentials.iss\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({\n labelers,\n viewer,\n xrpcEndpoint: app.bsky.feed.getFeedGenerators.$lxm,\n })\n const view = await getFeedGenerators({ ...params, hydrateCtx }, ctx)\n return {\n encoding: 'application/json',\n body: view,\n headers: resHeaders({ labelers: hydrateCtx.labelers }),\n }\n },\n })\n}\n\nconst skeleton = async (inputs: { params: Params }): Promise<Skeleton> => {\n return {\n feedUris: inputs.params.feeds,\n }\n}\n\nconst hydration = async (inputs: {\n ctx: Context\n params: Params\n skeleton: Skeleton\n}) => {\n const { ctx, params, skeleton } = inputs\n return await ctx.hydrator.hydrateFeedGens(\n skeleton.feedUris,\n params.hydrateCtx,\n )\n}\n\nconst presentation = (inputs: {\n ctx: Context\n skeleton: Skeleton\n hydration: HydrationState\n}) => {\n const { ctx, skeleton, hydration } = inputs\n const feeds = mapDefined(skeleton.feedUris, (uri) =>\n ctx.views.feedGenerator(uri, hydration),\n )\n return {\n feeds,\n }\n}\n\ntype Context = {\n hydrator: Hydrator\n views: Views\n}\n\ntype Params = app.bsky.feed.getFeedGenerators.$Params & {\n hydrateCtx: HydrateCtx\n}\n\ntype Skeleton = {\n feedUris: AtUriString[]\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"getLikes.d.ts","sourceRoot":"","sources":["../../../../../src/api/app/bsky/feed/getLikes.ts"],"names":[],"mappings":"AAOA,OAAO,EAAuB,KAAK,MAAM,EAAE,MAAM,sBAAsB,CAAA;AACvE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAaxD,MAAM,CAAC,OAAO,WAAW,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,QA6BvD"}
1
+ {"version":3,"file":"getLikes.d.ts","sourceRoot":"","sources":["../../../../../src/api/app/bsky/feed/getLikes.ts"],"names":[],"mappings":"AAOA,OAAO,EAAuB,KAAK,MAAM,EAAE,MAAM,sBAAsB,CAAA;AACvE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAaxD,MAAM,CAAC,OAAO,WAAW,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,QA8BvD"}
@@ -14,6 +14,7 @@ export default function (server, ctx) {
14
14
  const { viewer, includeTakedowns, skipViewerBlocks } = ctx.authVerifier.parseCreds(auth);
15
15
  const labelers = ctx.reqLabelers(req);
16
16
  const hydrateCtx = await ctx.hydrator.createContext({
17
+ xrpcEndpoint: app.bsky.feed.getLikes.$lxm,
17
18
  labelers,
18
19
  viewer,
19
20
  includeTakedowns,
@@ -1 +1 @@
1
- {"version":3,"file":"getLikes.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/feed/getLikes.ts"],"names":[],"mappings":"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","sourcesContent":["import { mapDefined } from '@atproto/common'\nimport {\n type AtUriString,\n type DatetimeString,\n type DidString,\n normalizeDatetimeAlways,\n} from '@atproto/syntax'\nimport { InvalidRequestError, type Server } from '@atproto/xrpc-server'\nimport type { AppContext } from '../../../../context.js'\nimport type {\n HydrateCtx,\n HydrationState,\n Hydrator,\n} from '../../../../hydration/hydrator.js'\nimport { parseString } from '../../../../hydration/util.js'\nimport { app } from '../../../../lexicons/index.js'\nimport { type RulesFnInput, createPipeline } from '../../../../pipeline.js'\nimport { uriToDid as creatorFromUri } from '../../../../util/uris.js'\nimport type { Views } from '../../../../views/index.js'\nimport { clearlyBadCursor, fillPage, resHeaders } from '../../../util.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const getLikes = createPipeline(skeleton, hydration, noBlocks, presentation)\n server.add(app.bsky.feed.getLikes, {\n auth: ctx.authVerifier.standardOptional,\n handler: async ({ params, auth, req }) => {\n const { viewer, includeTakedowns, skipViewerBlocks } =\n ctx.authVerifier.parseCreds(auth)\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({\n labelers,\n viewer,\n includeTakedowns,\n skipViewerBlocks,\n })\n const result = await fillPage({\n cursor: params.cursor,\n limit: params.limit,\n fetch: ({ cursor, limit }) =>\n getLikes({ ...params, cursor, limit, hydrateCtx }, ctx),\n items: (r) => r.likes,\n })\n\n return {\n encoding: 'application/json',\n body: result,\n headers: resHeaders({ labelers: hydrateCtx.labelers }),\n }\n },\n })\n}\n\nconst skeleton = async (inputs: {\n ctx: Context\n params: Params\n}): Promise<Skeleton> => {\n const { ctx, params } = inputs\n const authorDid = creatorFromUri(params.uri)\n\n if (clearlyBadCursor(params.cursor)) {\n return { authorDid, likes: [] }\n }\n if (looksLikeNonSortedCursor(params.cursor)) {\n throw new InvalidRequestError(\n 'Cursor appear to be out of date, please try reloading.',\n )\n }\n const likesRes = await ctx.hydrator.dataplane.getLikesBySubjectSorted({\n subject: { uri: params.uri, cid: params.cid },\n cursor: params.cursor,\n limit: params.limit,\n })\n return {\n authorDid,\n likes: likesRes.uris as AtUriString[],\n cursor: parseString(likesRes.cursor),\n }\n}\n\nconst hydration = async (inputs: {\n ctx: Context\n params: Params\n skeleton: Skeleton\n}) => {\n const { ctx, params, skeleton } = inputs\n const likesState = await ctx.hydrator.hydrateLikes(\n skeleton.authorDid,\n skeleton.likes,\n params.hydrateCtx,\n )\n return likesState\n}\n\nconst noBlocks = (input: RulesFnInput<Context, Params, Skeleton>) => {\n const { ctx, skeleton, hydration } = input\n\n skeleton.likes = skeleton.likes.filter((likeUri) => {\n const like = hydration.likes?.get(likeUri)\n if (!like) return false\n const likerDid = creatorFromUri(likeUri)\n return (\n !hydration.likeBlocks?.get(likeUri) &&\n !ctx.views.viewerBlockExists(likerDid, hydration)\n )\n })\n return skeleton\n}\n\nconst presentation = (inputs: {\n ctx: Context\n params: Params\n skeleton: Skeleton\n hydration: HydrationState\n}): app.bsky.feed.getLikes.$OutputBody => {\n const { ctx, params, skeleton, hydration } = inputs\n const likeViews = mapDefined(skeleton.likes, (uri) => {\n const like = hydration.likes?.get(uri)\n if (!like || !like.record) {\n return\n }\n const creatorDid = creatorFromUri(uri)\n const actor = ctx.views.profile(creatorDid, hydration)\n if (!actor) {\n return\n }\n return {\n actor,\n createdAt: normalizeDatetimeAlways(like.record.createdAt),\n indexedAt: like.sortedAt.toISOString() as DatetimeString,\n }\n })\n return {\n likes: likeViews,\n cursor: skeleton.cursor,\n uri: params.uri,\n cid: params.cid,\n }\n}\n\ntype Context = {\n hydrator: Hydrator\n views: Views\n}\n\ntype Params = app.bsky.feed.getLikes.$Params & { hydrateCtx: HydrateCtx }\n\ntype Skeleton = {\n authorDid: DidString\n likes: AtUriString[]\n cursor?: string\n}\n\nconst looksLikeNonSortedCursor = (cursor: string | undefined) => {\n // the old cursor values used with getLikesBySubject() were dids.\n // we now use getLikesBySubjectSorted(), whose cursors look like timestamps.\n return cursor?.startsWith('did:')\n}\n"]}
1
+ {"version":3,"file":"getLikes.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/feed/getLikes.ts"],"names":[],"mappings":"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","sourcesContent":["import { mapDefined } from '@atproto/common'\nimport {\n type AtUriString,\n type DatetimeString,\n type DidString,\n normalizeDatetimeAlways,\n} from '@atproto/syntax'\nimport { InvalidRequestError, type Server } from '@atproto/xrpc-server'\nimport type { AppContext } from '../../../../context.js'\nimport type {\n HydrateCtx,\n HydrationState,\n Hydrator,\n} from '../../../../hydration/hydrator.js'\nimport { parseString } from '../../../../hydration/util.js'\nimport { app } from '../../../../lexicons/index.js'\nimport { type RulesFnInput, createPipeline } from '../../../../pipeline.js'\nimport { uriToDid as creatorFromUri } from '../../../../util/uris.js'\nimport type { Views } from '../../../../views/index.js'\nimport { clearlyBadCursor, fillPage, resHeaders } from '../../../util.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const getLikes = createPipeline(skeleton, hydration, noBlocks, presentation)\n server.add(app.bsky.feed.getLikes, {\n auth: ctx.authVerifier.standardOptional,\n handler: async ({ params, auth, req }) => {\n const { viewer, includeTakedowns, skipViewerBlocks } =\n ctx.authVerifier.parseCreds(auth)\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({\n xrpcEndpoint: app.bsky.feed.getLikes.$lxm,\n labelers,\n viewer,\n includeTakedowns,\n skipViewerBlocks,\n })\n const result = await fillPage({\n cursor: params.cursor,\n limit: params.limit,\n fetch: ({ cursor, limit }) =>\n getLikes({ ...params, cursor, limit, hydrateCtx }, ctx),\n items: (r) => r.likes,\n })\n\n return {\n encoding: 'application/json',\n body: result,\n headers: resHeaders({ labelers: hydrateCtx.labelers }),\n }\n },\n })\n}\n\nconst skeleton = async (inputs: {\n ctx: Context\n params: Params\n}): Promise<Skeleton> => {\n const { ctx, params } = inputs\n const authorDid = creatorFromUri(params.uri)\n\n if (clearlyBadCursor(params.cursor)) {\n return { authorDid, likes: [] }\n }\n if (looksLikeNonSortedCursor(params.cursor)) {\n throw new InvalidRequestError(\n 'Cursor appear to be out of date, please try reloading.',\n )\n }\n const likesRes = await ctx.hydrator.dataplane.getLikesBySubjectSorted({\n subject: { uri: params.uri, cid: params.cid },\n cursor: params.cursor,\n limit: params.limit,\n })\n return {\n authorDid,\n likes: likesRes.uris as AtUriString[],\n cursor: parseString(likesRes.cursor),\n }\n}\n\nconst hydration = async (inputs: {\n ctx: Context\n params: Params\n skeleton: Skeleton\n}) => {\n const { ctx, params, skeleton } = inputs\n const likesState = await ctx.hydrator.hydrateLikes(\n skeleton.authorDid,\n skeleton.likes,\n params.hydrateCtx,\n )\n return likesState\n}\n\nconst noBlocks = (input: RulesFnInput<Context, Params, Skeleton>) => {\n const { ctx, skeleton, hydration } = input\n\n skeleton.likes = skeleton.likes.filter((likeUri) => {\n const like = hydration.likes?.get(likeUri)\n if (!like) return false\n const likerDid = creatorFromUri(likeUri)\n return (\n !hydration.likeBlocks?.get(likeUri) &&\n !ctx.views.viewerBlockExists(likerDid, hydration)\n )\n })\n return skeleton\n}\n\nconst presentation = (inputs: {\n ctx: Context\n params: Params\n skeleton: Skeleton\n hydration: HydrationState\n}): app.bsky.feed.getLikes.$OutputBody => {\n const { ctx, params, skeleton, hydration } = inputs\n const likeViews = mapDefined(skeleton.likes, (uri) => {\n const like = hydration.likes?.get(uri)\n if (!like || !like.record) {\n return\n }\n const creatorDid = creatorFromUri(uri)\n const actor = ctx.views.profile(creatorDid, hydration)\n if (!actor) {\n return\n }\n return {\n actor,\n createdAt: normalizeDatetimeAlways(like.record.createdAt),\n indexedAt: like.sortedAt.toISOString() as DatetimeString,\n }\n })\n return {\n likes: likeViews,\n cursor: skeleton.cursor,\n uri: params.uri,\n cid: params.cid,\n }\n}\n\ntype Context = {\n hydrator: Hydrator\n views: Views\n}\n\ntype Params = app.bsky.feed.getLikes.$Params & { hydrateCtx: HydrateCtx }\n\ntype Skeleton = {\n authorDid: DidString\n likes: AtUriString[]\n cursor?: string\n}\n\nconst looksLikeNonSortedCursor = (cursor: string | undefined) => {\n // the old cursor values used with getLikesBySubject() were dids.\n // we now use getLikesBySubjectSorted(), whose cursors look like timestamps.\n return cursor?.startsWith('did:')\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"getListFeed.d.ts","sourceRoot":"","sources":["../../../../../src/api/app/bsky/feed/getListFeed.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAA;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AACxD,OAAO,EACL,KAAK,eAAe,EAErB,MAAM,iCAAiC,CAAA;AACxC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAA;AAC7D,OAAO,EACL,KAAK,UAAU,EAEf,KAAK,QAAQ,EAEd,MAAM,mCAAmC,CAAA;AAE1C,OAAO,EAAE,GAAG,EAAE,MAAM,+BAA+B,CAAA;AAGnD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAA;AAGvD,MAAM,CAAC,OAAO,WAAW,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,QAyCvD;AAED,eAAO,MAAM,QAAQ,WAAkB;IACrC,GAAG,EAAE,OAAO,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;CACf,KAAG,OAAO,CAAC,QAAQ,CAuBnB,CAAA;AAyED,KAAK,OAAO,GAAG;IACb,QAAQ,EAAE,QAAQ,CAAA;IAClB,KAAK,EAAE,KAAK,CAAA;IACZ,SAAS,EAAE,eAAe,CAAA;CAC3B,CAAA;AAED,KAAK,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,GAAG;IAAE,UAAU,EAAE,UAAU,CAAA;CAAE,CAAA;AAE5E,KAAK,QAAQ,GAAG;IACd,KAAK,EAAE,QAAQ,EAAE,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,CAAA"}
1
+ {"version":3,"file":"getListFeed.d.ts","sourceRoot":"","sources":["../../../../../src/api/app/bsky/feed/getListFeed.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAA;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AACxD,OAAO,EACL,KAAK,eAAe,EAErB,MAAM,iCAAiC,CAAA;AACxC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAA;AAC7D,OAAO,EACL,KAAK,UAAU,EAEf,KAAK,QAAQ,EAEd,MAAM,mCAAmC,CAAA;AAE1C,OAAO,EAAE,GAAG,EAAE,MAAM,+BAA+B,CAAA;AAGnD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAA;AAGvD,MAAM,CAAC,OAAO,WAAW,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,QA0CvD;AAED,eAAO,MAAM,QAAQ,WAAkB;IACrC,GAAG,EAAE,OAAO,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;CACf,KAAG,OAAO,CAAC,QAAQ,CAuBnB,CAAA;AAyED,KAAK,OAAO,GAAG;IACb,QAAQ,EAAE,QAAQ,CAAA;IAClB,KAAK,EAAE,KAAK,CAAA;IACZ,SAAS,EAAE,eAAe,CAAA;CAC3B,CAAA;AAED,KAAK,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,GAAG;IAAE,UAAU,EAAE,UAAU,CAAA;CAAE,CAAA;AAE5E,KAAK,QAAQ,GAAG;IACd,KAAK,EAAE,QAAQ,EAAE,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,CAAA"}
@@ -14,6 +14,7 @@ export default function (server, ctx) {
14
14
  const viewer = auth.credentials.iss;
15
15
  const labelers = ctx.reqLabelers(req);
16
16
  const hydrateCtx = await ctx.hydrator.createContext({
17
+ xrpcEndpoint: app.bsky.feed.getListFeed.$lxm,
17
18
  labelers,
18
19
  viewer,
19
20
  features: ctx.featureGatesClient.scope(ctx.featureGatesClient.parseUserContextFromHandler({ viewer, req })),
@@ -1 +1 @@
1
- {"version":3,"file":"getListFeed.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/feed/getListFeed.ts"],"names":[],"mappings":"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","sourcesContent":["import { mapDefined } from '@atproto/common'\nimport type { AtUriString, DidString } from '@atproto/syntax'\nimport type { Server } from '@atproto/xrpc-server'\nimport type { AppContext } from '../../../../context.js'\nimport {\n type DataPlaneClient,\n asInvalidRequest,\n} from '../../../../data-plane/index.js'\nimport type { FeedItem } from '../../../../hydration/feed.js'\nimport {\n type HydrateCtx,\n type HydrationState,\n type Hydrator,\n mergeStates,\n} from '../../../../hydration/hydrator.js'\nimport { parseString } from '../../../../hydration/util.js'\nimport { app } from '../../../../lexicons/index.js'\nimport { createPipeline } from '../../../../pipeline.js'\nimport { uriToDid } from '../../../../util/uris.js'\nimport type { Views } from '../../../../views/index.js'\nimport { clearlyBadCursor, fillPage, resHeaders } from '../../../util.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const getListFeed = createPipeline(\n skeleton,\n hydration,\n noBlocksOrMutes,\n presentation,\n )\n server.add(app.bsky.feed.getListFeed, {\n auth: ctx.authVerifier.standardOptional,\n handler: async ({ params, auth, req }) => {\n const viewer = auth.credentials.iss\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({\n labelers,\n viewer,\n features: ctx.featureGatesClient.scope(\n ctx.featureGatesClient.parseUserContextFromHandler({ viewer, req }),\n ),\n })\n\n const result = await fillPage({\n cursor: params.cursor,\n limit: params.limit,\n // @NOTE the dataplane echoes `since` back as the cursor once the\n // bounded range is exhausted. Refilling past it would read below the\n // boundary.\n terminalCursor: params.since,\n fetch: ({ cursor, limit }) =>\n getListFeed({ ...params, cursor, limit, hydrateCtx }, ctx),\n items: (r) => r.feed,\n })\n\n const repoRev = await ctx.hydrator.actor.getRepoRevSafe(viewer)\n\n return {\n encoding: 'application/json',\n body: result,\n headers: resHeaders({ labelers: hydrateCtx.labelers, repoRev }),\n }\n },\n })\n}\n\nexport const skeleton = async (inputs: {\n ctx: Context\n params: Params\n}): Promise<Skeleton> => {\n const { ctx, params } = inputs\n if (clearlyBadCursor(params.cursor)) {\n return { items: [], cursor: params.since }\n }\n const res = await ctx.dataplane\n .getListFeed({\n listUri: params.list,\n limit: params.limit,\n cursor: params.cursor,\n since: params.since,\n })\n .catch(asInvalidRequest())\n return {\n items: res.items.map((item) => ({\n post: { uri: item.uri as AtUriString, cid: item.cid || undefined },\n repost: item.repost\n ? { uri: item.repost as AtUriString, cid: item.repostCid || undefined }\n : undefined,\n })),\n cursor: parseString(res.cursor),\n startCursor: parseString(res.startCursor),\n }\n}\n\nconst hydration = async (inputs: {\n ctx: Context\n params: Params\n skeleton: Skeleton\n}): Promise<HydrationState> => {\n const { ctx, params, skeleton } = inputs\n const [feedItemsState, bidirectionalBlocks] = await Promise.all([\n ctx.hydrator.hydrateFeedItems(skeleton.items, params.hydrateCtx),\n getBlocks({ ctx, params, skeleton }),\n ])\n return mergeStates(feedItemsState, {\n bidirectionalBlocks,\n })\n}\n\nconst noBlocksOrMutes = (inputs: {\n ctx: Context\n params: Params\n skeleton: Skeleton\n hydration: HydrationState\n}): Skeleton => {\n const { ctx, params, skeleton, hydration } = inputs\n skeleton.items = skeleton.items.filter((item) => {\n const bam = ctx.views.feedItemBlocksAndMutes(item, hydration)\n const creatorBlocks = hydration.bidirectionalBlocks?.get(\n uriToDid(params.list),\n )\n return (\n !bam.authorBlocked &&\n !bam.authorMuted &&\n !bam.authorQuotepostMuted &&\n !bam.originatorBlocked &&\n !bam.originatorMuted &&\n !bam.originatorRepostMuted &&\n !bam.ancestorAuthorBlocked &&\n !creatorBlocks?.get(uriToDid(item.post.uri))\n )\n })\n return skeleton\n}\n\nconst presentation = (inputs: {\n ctx: Context\n skeleton: Skeleton\n hydration: HydrationState\n}) => {\n const { ctx, skeleton, hydration } = inputs\n const feed = mapDefined(skeleton.items, (item) =>\n ctx.views.feedViewPost(item, hydration),\n )\n return {\n feed,\n cursor: skeleton.cursor,\n startCursor: skeleton.startCursor,\n }\n}\n\nconst getBlocks = async (input: {\n ctx: Context\n skeleton: Skeleton\n params: Params\n}) => {\n const { ctx, skeleton, params } = input\n const pairs: Map<DidString, DidString[]> = new Map()\n pairs.set(\n uriToDid(params.list),\n skeleton.items.map((item) => uriToDid(item.post.uri)),\n )\n return await ctx.hydrator.hydrateBidirectionalBlocks(pairs, params.hydrateCtx)\n}\n\ntype Context = {\n hydrator: Hydrator\n views: Views\n dataplane: DataPlaneClient\n}\n\ntype Params = app.bsky.feed.getListFeed.$Params & { hydrateCtx: HydrateCtx }\n\ntype Skeleton = {\n items: FeedItem[]\n cursor?: string\n startCursor?: string\n}\n"]}
1
+ {"version":3,"file":"getListFeed.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/feed/getListFeed.ts"],"names":[],"mappings":"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","sourcesContent":["import { mapDefined } from '@atproto/common'\nimport type { AtUriString, DidString } from '@atproto/syntax'\nimport type { Server } from '@atproto/xrpc-server'\nimport type { AppContext } from '../../../../context.js'\nimport {\n type DataPlaneClient,\n asInvalidRequest,\n} from '../../../../data-plane/index.js'\nimport type { FeedItem } from '../../../../hydration/feed.js'\nimport {\n type HydrateCtx,\n type HydrationState,\n type Hydrator,\n mergeStates,\n} from '../../../../hydration/hydrator.js'\nimport { parseString } from '../../../../hydration/util.js'\nimport { app } from '../../../../lexicons/index.js'\nimport { createPipeline } from '../../../../pipeline.js'\nimport { uriToDid } from '../../../../util/uris.js'\nimport type { Views } from '../../../../views/index.js'\nimport { clearlyBadCursor, fillPage, resHeaders } from '../../../util.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const getListFeed = createPipeline(\n skeleton,\n hydration,\n noBlocksOrMutes,\n presentation,\n )\n server.add(app.bsky.feed.getListFeed, {\n auth: ctx.authVerifier.standardOptional,\n handler: async ({ params, auth, req }) => {\n const viewer = auth.credentials.iss\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({\n xrpcEndpoint: app.bsky.feed.getListFeed.$lxm,\n labelers,\n viewer,\n features: ctx.featureGatesClient.scope(\n ctx.featureGatesClient.parseUserContextFromHandler({ viewer, req }),\n ),\n })\n\n const result = await fillPage({\n cursor: params.cursor,\n limit: params.limit,\n // @NOTE the dataplane echoes `since` back as the cursor once the\n // bounded range is exhausted. Refilling past it would read below the\n // boundary.\n terminalCursor: params.since,\n fetch: ({ cursor, limit }) =>\n getListFeed({ ...params, cursor, limit, hydrateCtx }, ctx),\n items: (r) => r.feed,\n })\n\n const repoRev = await ctx.hydrator.actor.getRepoRevSafe(viewer)\n\n return {\n encoding: 'application/json',\n body: result,\n headers: resHeaders({ labelers: hydrateCtx.labelers, repoRev }),\n }\n },\n })\n}\n\nexport const skeleton = async (inputs: {\n ctx: Context\n params: Params\n}): Promise<Skeleton> => {\n const { ctx, params } = inputs\n if (clearlyBadCursor(params.cursor)) {\n return { items: [], cursor: params.since }\n }\n const res = await ctx.dataplane\n .getListFeed({\n listUri: params.list,\n limit: params.limit,\n cursor: params.cursor,\n since: params.since,\n })\n .catch(asInvalidRequest())\n return {\n items: res.items.map((item) => ({\n post: { uri: item.uri as AtUriString, cid: item.cid || undefined },\n repost: item.repost\n ? { uri: item.repost as AtUriString, cid: item.repostCid || undefined }\n : undefined,\n })),\n cursor: parseString(res.cursor),\n startCursor: parseString(res.startCursor),\n }\n}\n\nconst hydration = async (inputs: {\n ctx: Context\n params: Params\n skeleton: Skeleton\n}): Promise<HydrationState> => {\n const { ctx, params, skeleton } = inputs\n const [feedItemsState, bidirectionalBlocks] = await Promise.all([\n ctx.hydrator.hydrateFeedItems(skeleton.items, params.hydrateCtx),\n getBlocks({ ctx, params, skeleton }),\n ])\n return mergeStates(feedItemsState, {\n bidirectionalBlocks,\n })\n}\n\nconst noBlocksOrMutes = (inputs: {\n ctx: Context\n params: Params\n skeleton: Skeleton\n hydration: HydrationState\n}): Skeleton => {\n const { ctx, params, skeleton, hydration } = inputs\n skeleton.items = skeleton.items.filter((item) => {\n const bam = ctx.views.feedItemBlocksAndMutes(item, hydration)\n const creatorBlocks = hydration.bidirectionalBlocks?.get(\n uriToDid(params.list),\n )\n return (\n !bam.authorBlocked &&\n !bam.authorMuted &&\n !bam.authorQuotepostMuted &&\n !bam.originatorBlocked &&\n !bam.originatorMuted &&\n !bam.originatorRepostMuted &&\n !bam.ancestorAuthorBlocked &&\n !creatorBlocks?.get(uriToDid(item.post.uri))\n )\n })\n return skeleton\n}\n\nconst presentation = (inputs: {\n ctx: Context\n skeleton: Skeleton\n hydration: HydrationState\n}) => {\n const { ctx, skeleton, hydration } = inputs\n const feed = mapDefined(skeleton.items, (item) =>\n ctx.views.feedViewPost(item, hydration),\n )\n return {\n feed,\n cursor: skeleton.cursor,\n startCursor: skeleton.startCursor,\n }\n}\n\nconst getBlocks = async (input: {\n ctx: Context\n skeleton: Skeleton\n params: Params\n}) => {\n const { ctx, skeleton, params } = input\n const pairs: Map<DidString, DidString[]> = new Map()\n pairs.set(\n uriToDid(params.list),\n skeleton.items.map((item) => uriToDid(item.post.uri)),\n )\n return await ctx.hydrator.hydrateBidirectionalBlocks(pairs, params.hydrateCtx)\n}\n\ntype Context = {\n hydrator: Hydrator\n views: Views\n dataplane: DataPlaneClient\n}\n\ntype Params = app.bsky.feed.getListFeed.$Params & { hydrateCtx: HydrateCtx }\n\ntype Skeleton = {\n items: FeedItem[]\n cursor?: string\n startCursor?: string\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"getPostThread.d.ts","sourceRoot":"","sources":["../../../../../src/api/app/bsky/feed/getPostThread.ts"],"names":[],"mappings":"AACA,OAAO,EAAuB,KAAK,MAAM,EAAE,MAAM,sBAAsB,CAAA;AAEvE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAmBxD,MAAM,CAAC,OAAO,WAAW,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,QAiDvD"}
1
+ {"version":3,"file":"getPostThread.d.ts","sourceRoot":"","sources":["../../../../../src/api/app/bsky/feed/getPostThread.ts"],"names":[],"mappings":"AACA,OAAO,EAAuB,KAAK,MAAM,EAAE,MAAM,sBAAsB,CAAA;AAEvE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAmBxD,MAAM,CAAC,OAAO,WAAW,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,QAkDvD"}
@@ -18,6 +18,7 @@ export default function (server, ctx) {
18
18
  const { viewer, includeTakedowns, include3pBlocks, skipViewerBlocks } = ctx.authVerifier.parseCreds(auth);
19
19
  const labelers = ctx.reqLabelers(req);
20
20
  const hydrateCtx = await ctx.hydrator.createContext({
21
+ xrpcEndpoint: app.bsky.feed.getPostThread.$lxm,
21
22
  labelers,
22
23
  viewer,
23
24
  includeTakedowns,
@@ -1 +1 @@
1
- {"version":3,"file":"getPostThread.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/feed/getPostThread.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AtUriString } from '@atproto/syntax'\nimport { InvalidRequestError, type Server } from '@atproto/xrpc-server'\nimport type { ServerConfig } from '../../../../config.js'\nimport type { AppContext } from '../../../../context.js'\nimport {\n Code,\n type DataPlaneClient,\n isDataplaneError,\n} from '../../../../data-plane/index.js'\nimport type { HydrateCtx, Hydrator } from '../../../../hydration/hydrator.js'\nimport { app } from '../../../../lexicons/index.js'\nimport {\n type HydrationFnInput,\n type PresentationFnInput,\n type SkeletonFnInput,\n createPipeline,\n noRules,\n} from '../../../../pipeline.js'\nimport { postUriToThreadgateUri } from '../../../../util/uris.js'\nimport type { Views } from '../../../../views/index.js'\nimport { ATPROTO_REPO_REV, resHeaders } from '../../../util.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const getPostThread = createPipeline(\n skeleton,\n hydration,\n noRules, // handled in presentation: 3p block-violating replies are turned to #blockedPost, viewer blocks turned to #notFoundPost.\n presentation,\n )\n server.add(app.bsky.feed.getPostThread, {\n auth: ctx.authVerifier.optionalStandardOrRole,\n opts: {\n // @TODO remove after grace period has passed, behavior is non-standard.\n // temporarily added for compat w/ previous version of xrpc-server to avoid breakage of a few specified parties.\n paramsParseLoose: true,\n },\n handler: async ({ params, auth, req, res }) => {\n const { viewer, includeTakedowns, include3pBlocks, skipViewerBlocks } =\n ctx.authVerifier.parseCreds(auth)\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({\n labelers,\n viewer,\n includeTakedowns,\n include3pBlocks,\n skipViewerBlocks,\n })\n\n let result: app.bsky.feed.getPostThread.$OutputBody\n try {\n result = await getPostThread({ ...params, hydrateCtx }, ctx)\n } catch (err) {\n const repoRev = await ctx.hydrator.actor.getRepoRevSafe(viewer)\n if (repoRev) {\n res.setHeader(ATPROTO_REPO_REV, repoRev)\n }\n throw err\n }\n\n const repoRev = await ctx.hydrator.actor.getRepoRevSafe(viewer)\n\n return {\n encoding: 'application/json',\n body: result,\n headers: resHeaders({\n repoRev,\n labelers: hydrateCtx.labelers,\n }),\n }\n },\n })\n}\n\nconst skeleton = async (\n inputs: SkeletonFnInput<Context, Params>,\n): Promise<Skeleton> => {\n const { ctx, params } = inputs\n const anchor = await ctx.hydrator.resolveUri(params.uri)\n try {\n const res = await ctx.dataplane.getThread({\n postUri: anchor,\n above: params.parentHeight,\n below: getDepth(ctx, anchor, params),\n })\n return {\n anchor,\n uris: res.uris as AtUriString[],\n }\n } catch (err) {\n if (isDataplaneError(err, Code.NotFound)) {\n return {\n anchor,\n uris: [],\n }\n } else {\n throw err\n }\n }\n}\n\nconst hydration = async (\n inputs: HydrationFnInput<Context, Params, Skeleton>,\n) => {\n const { ctx, params, skeleton } = inputs\n return ctx.hydrator.hydrateThreadPosts(\n skeleton.uris.map((uri) => ({ uri })),\n params.hydrateCtx,\n )\n}\n\nconst presentation = (\n inputs: PresentationFnInput<Context, Params, Skeleton>,\n) => {\n const { ctx, params, skeleton, hydration } = inputs\n const thread = ctx.views.thread(skeleton, hydration, {\n height: params.parentHeight!,\n depth: getDepth(ctx, skeleton.anchor, params),\n })\n if (app.bsky.feed.defs.notFoundPost.$isTypeOf(thread)) {\n // @TODO technically this could be returned as a NotFoundPost based on lexicon\n throw new InvalidRequestError(\n `Post not found: ${skeleton.anchor}`,\n 'NotFound',\n )\n }\n const rootUri =\n hydration.posts?.get(skeleton.anchor)?.record.reply?.root.uri ??\n skeleton.anchor\n const threadgate = ctx.views.threadgate(\n postUriToThreadgateUri(rootUri),\n hydration,\n )\n return { thread, threadgate }\n}\n\ntype Context = {\n dataplane: DataPlaneClient\n hydrator: Hydrator\n views: Views\n cfg: ServerConfig\n}\n\ntype Params = app.bsky.feed.getPostThread.$Params & { hydrateCtx: HydrateCtx }\n\ntype Skeleton = {\n anchor: AtUriString\n uris: AtUriString[]\n}\n\nconst getDepth = (ctx: Context, anchor: string, params: Params) => {\n let maxDepth = ctx.cfg.maxThreadDepth\n if (ctx.cfg.bigThreadUris.has(anchor) && ctx.cfg.bigThreadDepth) {\n maxDepth = ctx.cfg.bigThreadDepth\n }\n return maxDepth ? Math.min(maxDepth, params.depth!) : params.depth!\n}\n"]}
1
+ {"version":3,"file":"getPostThread.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/feed/getPostThread.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AtUriString } from '@atproto/syntax'\nimport { InvalidRequestError, type Server } from '@atproto/xrpc-server'\nimport type { ServerConfig } from '../../../../config.js'\nimport type { AppContext } from '../../../../context.js'\nimport {\n Code,\n type DataPlaneClient,\n isDataplaneError,\n} from '../../../../data-plane/index.js'\nimport type { HydrateCtx, Hydrator } from '../../../../hydration/hydrator.js'\nimport { app } from '../../../../lexicons/index.js'\nimport {\n type HydrationFnInput,\n type PresentationFnInput,\n type SkeletonFnInput,\n createPipeline,\n noRules,\n} from '../../../../pipeline.js'\nimport { postUriToThreadgateUri } from '../../../../util/uris.js'\nimport type { Views } from '../../../../views/index.js'\nimport { ATPROTO_REPO_REV, resHeaders } from '../../../util.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const getPostThread = createPipeline(\n skeleton,\n hydration,\n noRules, // handled in presentation: 3p block-violating replies are turned to #blockedPost, viewer blocks turned to #notFoundPost.\n presentation,\n )\n server.add(app.bsky.feed.getPostThread, {\n auth: ctx.authVerifier.optionalStandardOrRole,\n opts: {\n // @TODO remove after grace period has passed, behavior is non-standard.\n // temporarily added for compat w/ previous version of xrpc-server to avoid breakage of a few specified parties.\n paramsParseLoose: true,\n },\n handler: async ({ params, auth, req, res }) => {\n const { viewer, includeTakedowns, include3pBlocks, skipViewerBlocks } =\n ctx.authVerifier.parseCreds(auth)\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({\n xrpcEndpoint: app.bsky.feed.getPostThread.$lxm,\n labelers,\n viewer,\n includeTakedowns,\n include3pBlocks,\n skipViewerBlocks,\n })\n\n let result: app.bsky.feed.getPostThread.$OutputBody\n try {\n result = await getPostThread({ ...params, hydrateCtx }, ctx)\n } catch (err) {\n const repoRev = await ctx.hydrator.actor.getRepoRevSafe(viewer)\n if (repoRev) {\n res.setHeader(ATPROTO_REPO_REV, repoRev)\n }\n throw err\n }\n\n const repoRev = await ctx.hydrator.actor.getRepoRevSafe(viewer)\n\n return {\n encoding: 'application/json',\n body: result,\n headers: resHeaders({\n repoRev,\n labelers: hydrateCtx.labelers,\n }),\n }\n },\n })\n}\n\nconst skeleton = async (\n inputs: SkeletonFnInput<Context, Params>,\n): Promise<Skeleton> => {\n const { ctx, params } = inputs\n const anchor = await ctx.hydrator.resolveUri(params.uri)\n try {\n const res = await ctx.dataplane.getThread({\n postUri: anchor,\n above: params.parentHeight,\n below: getDepth(ctx, anchor, params),\n })\n return {\n anchor,\n uris: res.uris as AtUriString[],\n }\n } catch (err) {\n if (isDataplaneError(err, Code.NotFound)) {\n return {\n anchor,\n uris: [],\n }\n } else {\n throw err\n }\n }\n}\n\nconst hydration = async (\n inputs: HydrationFnInput<Context, Params, Skeleton>,\n) => {\n const { ctx, params, skeleton } = inputs\n return ctx.hydrator.hydrateThreadPosts(\n skeleton.uris.map((uri) => ({ uri })),\n params.hydrateCtx,\n )\n}\n\nconst presentation = (\n inputs: PresentationFnInput<Context, Params, Skeleton>,\n) => {\n const { ctx, params, skeleton, hydration } = inputs\n const thread = ctx.views.thread(skeleton, hydration, {\n height: params.parentHeight!,\n depth: getDepth(ctx, skeleton.anchor, params),\n })\n if (app.bsky.feed.defs.notFoundPost.$isTypeOf(thread)) {\n // @TODO technically this could be returned as a NotFoundPost based on lexicon\n throw new InvalidRequestError(\n `Post not found: ${skeleton.anchor}`,\n 'NotFound',\n )\n }\n const rootUri =\n hydration.posts?.get(skeleton.anchor)?.record.reply?.root.uri ??\n skeleton.anchor\n const threadgate = ctx.views.threadgate(\n postUriToThreadgateUri(rootUri),\n hydration,\n )\n return { thread, threadgate }\n}\n\ntype Context = {\n dataplane: DataPlaneClient\n hydrator: Hydrator\n views: Views\n cfg: ServerConfig\n}\n\ntype Params = app.bsky.feed.getPostThread.$Params & { hydrateCtx: HydrateCtx }\n\ntype Skeleton = {\n anchor: AtUriString\n uris: AtUriString[]\n}\n\nconst getDepth = (ctx: Context, anchor: string, params: Params) => {\n let maxDepth = ctx.cfg.maxThreadDepth\n if (ctx.cfg.bigThreadUris.has(anchor) && ctx.cfg.bigThreadDepth) {\n maxDepth = ctx.cfg.bigThreadDepth\n }\n return maxDepth ? Math.min(maxDepth, params.depth!) : params.depth!\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"getPosts.d.ts","sourceRoot":"","sources":["../../../../../src/api/app/bsky/feed/getPosts.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAA;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAYxD,MAAM,CAAC,OAAO,WAAW,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,QA+BvD"}
1
+ {"version":3,"file":"getPosts.d.ts","sourceRoot":"","sources":["../../../../../src/api/app/bsky/feed/getPosts.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAA;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAYxD,MAAM,CAAC,OAAO,WAAW,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,QAmCvD"}
@@ -22,7 +22,11 @@ export default function (server, ctx) {
22
22
  handler: async ({ params, auth, req }) => {
23
23
  const viewer = auth.credentials.iss;
24
24
  const labelers = ctx.reqLabelers(req);
25
- const hydrateCtx = await ctx.hydrator.createContext({ labelers, viewer });
25
+ const hydrateCtx = await ctx.hydrator.createContext({
26
+ xrpcEndpoint: app.bsky.feed.getPosts.$lxm,
27
+ labelers,
28
+ viewer,
29
+ });
26
30
  const results = await getPosts({ ...params, hydrateCtx }, ctx);
27
31
  return {
28
32
  encoding: 'application/json',
@@ -1 +1 @@
1
- {"version":3,"file":"getPosts.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/feed/getPosts.ts"],"names":[],"mappings":"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","sourcesContent":["import { dedupeStrs, mapDefined } from '@atproto/common'\nimport type { AtUriString } from '@atproto/syntax'\nimport type { Server } from '@atproto/xrpc-server'\nimport type { AppContext } from '../../../../context.js'\nimport type {\n HydrateCtx,\n HydrationState,\n Hydrator,\n} from '../../../../hydration/hydrator.js'\nimport { app } from '../../../../lexicons/index.js'\nimport { createPipeline } from '../../../../pipeline.js'\nimport { uriToDid as creatorFromUri } from '../../../../util/uris.js'\nimport type { Views } from '../../../../views/index.js'\nimport { resHeaders } from '../../../util.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const getPosts = createPipeline(skeleton, hydration, noBlocks, presentation)\n server.add(app.bsky.feed.getPosts, {\n auth: ctx.authVerifier.standardOptionalParameterized({\n lxmCheck: (method) => {\n if (!method) return false\n return (\n method === app.bsky.feed.getPosts.$lxm ||\n method.startsWith('chat.bsky.')\n )\n },\n }),\n opts: {\n // @TODO remove after grace period has passed, behavior is non-standard.\n // temporarily added for compat w/ previous version of xrpc-server to avoid breakage of a few specified parties.\n paramsParseLoose: true,\n },\n handler: async ({ params, auth, req }) => {\n const viewer = auth.credentials.iss\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({ labelers, viewer })\n\n const results = await getPosts({ ...params, hydrateCtx }, ctx)\n\n return {\n encoding: 'application/json',\n body: results,\n headers: resHeaders({ labelers: hydrateCtx.labelers }),\n }\n },\n })\n}\n\nconst skeleton = async (inputs: { params: Params }): Promise<Skeleton> => {\n return { posts: dedupeStrs(inputs.params.uris) }\n}\n\nconst hydration = async (inputs: {\n ctx: Context\n params: Params\n skeleton: Skeleton\n}) => {\n const { ctx, params, skeleton } = inputs\n return ctx.hydrator.hydratePosts(\n skeleton.posts.map((uri) => ({ uri })),\n params.hydrateCtx,\n )\n}\n\nconst noBlocks = (inputs: {\n ctx: Context\n skeleton: Skeleton\n hydration: HydrationState\n}) => {\n const { ctx, skeleton, hydration } = inputs\n skeleton.posts = skeleton.posts.filter((uri) => {\n const creator = creatorFromUri(uri)\n return !ctx.views.viewerBlockExists(creator, hydration)\n })\n return skeleton\n}\n\nconst presentation = (inputs: {\n ctx: Context\n params: Params\n skeleton: Skeleton\n hydration: HydrationState\n}) => {\n const { ctx, skeleton, hydration } = inputs\n const posts = mapDefined(skeleton.posts, (uri) =>\n ctx.views.post(uri, hydration),\n )\n return { posts }\n}\n\ntype Context = {\n hydrator: Hydrator\n views: Views\n}\n\ntype Params = app.bsky.feed.getPosts.$Params & { hydrateCtx: HydrateCtx }\n\ntype Skeleton = {\n posts: AtUriString[]\n}\n"]}
1
+ {"version":3,"file":"getPosts.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/feed/getPosts.ts"],"names":[],"mappings":"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","sourcesContent":["import { dedupeStrs, mapDefined } from '@atproto/common'\nimport type { AtUriString } from '@atproto/syntax'\nimport type { Server } from '@atproto/xrpc-server'\nimport type { AppContext } from '../../../../context.js'\nimport type {\n HydrateCtx,\n HydrationState,\n Hydrator,\n} from '../../../../hydration/hydrator.js'\nimport { app } from '../../../../lexicons/index.js'\nimport { createPipeline } from '../../../../pipeline.js'\nimport { uriToDid as creatorFromUri } from '../../../../util/uris.js'\nimport type { Views } from '../../../../views/index.js'\nimport { resHeaders } from '../../../util.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const getPosts = createPipeline(skeleton, hydration, noBlocks, presentation)\n server.add(app.bsky.feed.getPosts, {\n auth: ctx.authVerifier.standardOptionalParameterized({\n lxmCheck: (method) => {\n if (!method) return false\n return (\n method === app.bsky.feed.getPosts.$lxm ||\n method.startsWith('chat.bsky.')\n )\n },\n }),\n opts: {\n // @TODO remove after grace period has passed, behavior is non-standard.\n // temporarily added for compat w/ previous version of xrpc-server to avoid breakage of a few specified parties.\n paramsParseLoose: true,\n },\n handler: async ({ params, auth, req }) => {\n const viewer = auth.credentials.iss\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({\n xrpcEndpoint: app.bsky.feed.getPosts.$lxm,\n labelers,\n viewer,\n })\n\n const results = await getPosts({ ...params, hydrateCtx }, ctx)\n\n return {\n encoding: 'application/json',\n body: results,\n headers: resHeaders({ labelers: hydrateCtx.labelers }),\n }\n },\n })\n}\n\nconst skeleton = async (inputs: { params: Params }): Promise<Skeleton> => {\n return { posts: dedupeStrs(inputs.params.uris) }\n}\n\nconst hydration = async (inputs: {\n ctx: Context\n params: Params\n skeleton: Skeleton\n}) => {\n const { ctx, params, skeleton } = inputs\n return ctx.hydrator.hydratePosts(\n skeleton.posts.map((uri) => ({ uri })),\n params.hydrateCtx,\n )\n}\n\nconst noBlocks = (inputs: {\n ctx: Context\n skeleton: Skeleton\n hydration: HydrationState\n}) => {\n const { ctx, skeleton, hydration } = inputs\n skeleton.posts = skeleton.posts.filter((uri) => {\n const creator = creatorFromUri(uri)\n return !ctx.views.viewerBlockExists(creator, hydration)\n })\n return skeleton\n}\n\nconst presentation = (inputs: {\n ctx: Context\n params: Params\n skeleton: Skeleton\n hydration: HydrationState\n}) => {\n const { ctx, skeleton, hydration } = inputs\n const posts = mapDefined(skeleton.posts, (uri) =>\n ctx.views.post(uri, hydration),\n )\n return { posts }\n}\n\ntype Context = {\n hydrator: Hydrator\n views: Views\n}\n\ntype Params = app.bsky.feed.getPosts.$Params & { hydrateCtx: HydrateCtx }\n\ntype Skeleton = {\n posts: AtUriString[]\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"getQuotes.d.ts","sourceRoot":"","sources":["../../../../../src/api/app/bsky/feed/getQuotes.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAA;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAaxD,MAAM,CAAC,OAAO,WAAW,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,QAiCvD"}
1
+ {"version":3,"file":"getQuotes.d.ts","sourceRoot":"","sources":["../../../../../src/api/app/bsky/feed/getQuotes.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAA;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAaxD,MAAM,CAAC,OAAO,WAAW,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,QAkCvD"}
@@ -12,6 +12,7 @@ export default function (server, ctx) {
12
12
  const { viewer, includeTakedowns, skipViewerBlocks } = ctx.authVerifier.parseCreds(auth);
13
13
  const labelers = ctx.reqLabelers(req);
14
14
  const hydrateCtx = await ctx.hydrator.createContext({
15
+ xrpcEndpoint: app.bsky.feed.getQuotes.$lxm,
15
16
  labelers,
16
17
  viewer,
17
18
  includeTakedowns,