@atproto/bsky 0.0.75 → 0.0.77

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (268) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/api/app/bsky/actor/getProfiles.d.ts.map +1 -1
  3. package/dist/api/app/bsky/actor/getProfiles.js +9 -1
  4. package/dist/api/app/bsky/actor/getProfiles.js.map +1 -1
  5. package/dist/api/app/bsky/actor/searchActorsTypeahead.js +10 -2
  6. package/dist/api/app/bsky/actor/searchActorsTypeahead.js.map +1 -1
  7. package/dist/api/app/bsky/feed/getActorLikes.js +2 -2
  8. package/dist/api/app/bsky/feed/getActorLikes.js.map +1 -1
  9. package/dist/api/app/bsky/feed/getFeed.d.ts.map +1 -1
  10. package/dist/api/app/bsky/feed/getFeed.js +8 -1
  11. package/dist/api/app/bsky/feed/getFeed.js.map +1 -1
  12. package/dist/api/app/bsky/feed/getLikes.js +6 -6
  13. package/dist/api/app/bsky/feed/getLikes.js.map +1 -1
  14. package/dist/api/app/bsky/feed/getPosts.d.ts.map +1 -1
  15. package/dist/api/app/bsky/feed/getPosts.js +12 -5
  16. package/dist/api/app/bsky/feed/getPosts.js.map +1 -1
  17. package/dist/api/app/bsky/feed/getQuotes.d.ts +4 -0
  18. package/dist/api/app/bsky/feed/getQuotes.d.ts.map +1 -0
  19. package/dist/api/app/bsky/feed/getQuotes.js +67 -0
  20. package/dist/api/app/bsky/feed/getQuotes.js.map +1 -0
  21. package/dist/api/app/bsky/feed/getRepostedBy.js +6 -6
  22. package/dist/api/app/bsky/feed/getRepostedBy.js.map +1 -1
  23. package/dist/api/app/bsky/feed/searchPosts.js +4 -4
  24. package/dist/api/app/bsky/feed/searchPosts.js.map +1 -1
  25. package/dist/api/app/bsky/graph/getFollowers.js +8 -8
  26. package/dist/api/app/bsky/graph/getFollowers.js.map +1 -1
  27. package/dist/api/app/bsky/graph/getList.d.ts.map +1 -1
  28. package/dist/api/app/bsky/graph/getList.js +32 -2
  29. package/dist/api/app/bsky/graph/getList.js.map +1 -1
  30. package/dist/api/app/bsky/notification/listNotifications.d.ts.map +1 -1
  31. package/dist/api/app/bsky/notification/listNotifications.js +29 -8
  32. package/dist/api/app/bsky/notification/listNotifications.js.map +1 -1
  33. package/dist/api/index.d.ts.map +1 -1
  34. package/dist/api/index.js +2 -0
  35. package/dist/api/index.js.map +1 -1
  36. package/dist/auth-verifier.d.ts +8 -3
  37. package/dist/auth-verifier.d.ts.map +1 -1
  38. package/dist/auth-verifier.js +43 -29
  39. package/dist/auth-verifier.js.map +1 -1
  40. package/dist/data-plane/server/db/database-schema.d.ts +4 -2
  41. package/dist/data-plane/server/db/database-schema.d.ts.map +1 -1
  42. package/dist/data-plane/server/db/migrations/20240723T220700077Z-quotes-post-aggs.d.ts +4 -0
  43. package/dist/data-plane/server/db/migrations/20240723T220700077Z-quotes-post-aggs.d.ts.map +1 -0
  44. package/dist/data-plane/server/db/migrations/20240723T220700077Z-quotes-post-aggs.js +15 -0
  45. package/dist/data-plane/server/db/migrations/20240723T220700077Z-quotes-post-aggs.js.map +1 -0
  46. package/dist/data-plane/server/db/migrations/20240723T220703655Z-quotes.d.ts +4 -0
  47. package/dist/data-plane/server/db/migrations/20240723T220703655Z-quotes.d.ts.map +1 -0
  48. package/dist/data-plane/server/db/migrations/20240723T220703655Z-quotes.js +30 -0
  49. package/dist/data-plane/server/db/migrations/20240723T220703655Z-quotes.js.map +1 -0
  50. package/dist/data-plane/server/db/migrations/20240801T193939827Z-post-gate.d.ts +4 -0
  51. package/dist/data-plane/server/db/migrations/20240801T193939827Z-post-gate.d.ts.map +1 -0
  52. package/dist/data-plane/server/db/migrations/20240801T193939827Z-post-gate.js +20 -0
  53. package/dist/data-plane/server/db/migrations/20240801T193939827Z-post-gate.js.map +1 -0
  54. package/dist/data-plane/server/db/migrations/20240808T224251220Z-post-gate-flags.d.ts +4 -0
  55. package/dist/data-plane/server/db/migrations/20240808T224251220Z-post-gate-flags.d.ts.map +1 -0
  56. package/dist/data-plane/server/db/migrations/20240808T224251220Z-post-gate-flags.js +28 -0
  57. package/dist/data-plane/server/db/migrations/20240808T224251220Z-post-gate-flags.js.map +1 -0
  58. package/dist/data-plane/server/db/migrations/index.d.ts +4 -0
  59. package/dist/data-plane/server/db/migrations/index.d.ts.map +1 -1
  60. package/dist/data-plane/server/db/migrations/index.js +5 -1
  61. package/dist/data-plane/server/db/migrations/index.js.map +1 -1
  62. package/dist/data-plane/server/db/tables/post-agg.d.ts +1 -0
  63. package/dist/data-plane/server/db/tables/post-agg.d.ts.map +1 -1
  64. package/dist/data-plane/server/db/tables/post-gate.d.ts +14 -0
  65. package/dist/data-plane/server/db/tables/post-gate.d.ts.map +1 -0
  66. package/dist/data-plane/server/db/tables/post-gate.js +4 -0
  67. package/dist/data-plane/server/db/tables/post-gate.js.map +1 -0
  68. package/dist/data-plane/server/db/tables/post.d.ts +3 -0
  69. package/dist/data-plane/server/db/tables/post.d.ts.map +1 -1
  70. package/dist/data-plane/server/db/tables/quote.d.ts +16 -0
  71. package/dist/data-plane/server/db/tables/quote.d.ts.map +1 -0
  72. package/dist/data-plane/server/db/tables/quote.js +4 -0
  73. package/dist/data-plane/server/db/tables/quote.js.map +1 -0
  74. package/dist/data-plane/server/indexing/index.d.ts +2 -0
  75. package/dist/data-plane/server/indexing/index.d.ts.map +1 -1
  76. package/dist/data-plane/server/indexing/index.js +6 -0
  77. package/dist/data-plane/server/indexing/index.js.map +1 -1
  78. package/dist/data-plane/server/indexing/plugins/post-gate.d.ts +10 -0
  79. package/dist/data-plane/server/indexing/plugins/post-gate.d.ts.map +1 -0
  80. package/dist/data-plane/server/indexing/plugins/post-gate.js +101 -0
  81. package/dist/data-plane/server/indexing/plugins/post-gate.js.map +1 -0
  82. package/dist/data-plane/server/indexing/plugins/post.d.ts +2 -0
  83. package/dist/data-plane/server/indexing/plugins/post.d.ts.map +1 -1
  84. package/dist/data-plane/server/indexing/plugins/post.js +122 -15
  85. package/dist/data-plane/server/indexing/plugins/post.js.map +1 -1
  86. package/dist/data-plane/server/indexing/plugins/thread-gate.d.ts.map +1 -1
  87. package/dist/data-plane/server/indexing/plugins/thread-gate.js +12 -0
  88. package/dist/data-plane/server/indexing/plugins/thread-gate.js.map +1 -1
  89. package/dist/data-plane/server/routes/index.d.ts.map +1 -1
  90. package/dist/data-plane/server/routes/index.js +2 -0
  91. package/dist/data-plane/server/routes/index.js.map +1 -1
  92. package/dist/data-plane/server/routes/interactions.d.ts.map +1 -1
  93. package/dist/data-plane/server/routes/interactions.js +2 -1
  94. package/dist/data-plane/server/routes/interactions.js.map +1 -1
  95. package/dist/data-plane/server/routes/quotes.d.ts +6 -0
  96. package/dist/data-plane/server/routes/quotes.d.ts.map +1 -0
  97. package/dist/data-plane/server/routes/quotes.js +27 -0
  98. package/dist/data-plane/server/routes/quotes.js.map +1 -0
  99. package/dist/data-plane/server/routes/records.d.ts.map +1 -1
  100. package/dist/data-plane/server/routes/records.js +11 -1
  101. package/dist/data-plane/server/routes/records.js.map +1 -1
  102. package/dist/data-plane/server/util.d.ts +6 -7
  103. package/dist/data-plane/server/util.d.ts.map +1 -1
  104. package/dist/data-plane/server/util.js +1 -9
  105. package/dist/data-plane/server/util.js.map +1 -1
  106. package/dist/hydration/feed.d.ts +10 -0
  107. package/dist/hydration/feed.d.ts.map +1 -1
  108. package/dist/hydration/feed.js +31 -7
  109. package/dist/hydration/feed.js.map +1 -1
  110. package/dist/hydration/hydrator.d.ts +5 -2
  111. package/dist/hydration/hydrator.d.ts.map +1 -1
  112. package/dist/hydration/hydrator.js +102 -38
  113. package/dist/hydration/hydrator.js.map +1 -1
  114. package/dist/hydration/util.d.ts +0 -1
  115. package/dist/hydration/util.d.ts.map +1 -1
  116. package/dist/hydration/util.js +1 -5
  117. package/dist/hydration/util.js.map +1 -1
  118. package/dist/lexicon/index.d.ts +2 -0
  119. package/dist/lexicon/index.d.ts.map +1 -1
  120. package/dist/lexicon/index.js +4 -0
  121. package/dist/lexicon/index.js.map +1 -1
  122. package/dist/lexicon/lexicons.d.ts +141 -0
  123. package/dist/lexicon/lexicons.d.ts.map +1 -1
  124. package/dist/lexicon/lexicons.js +142 -0
  125. package/dist/lexicon/lexicons.js.map +1 -1
  126. package/dist/lexicon/types/app/bsky/embed/record.d.ts +8 -1
  127. package/dist/lexicon/types/app/bsky/embed/record.d.ts.map +1 -1
  128. package/dist/lexicon/types/app/bsky/embed/record.js +11 -1
  129. package/dist/lexicon/types/app/bsky/embed/record.js.map +1 -1
  130. package/dist/lexicon/types/app/bsky/feed/defs.d.ts +2 -0
  131. package/dist/lexicon/types/app/bsky/feed/defs.d.ts.map +1 -1
  132. package/dist/lexicon/types/app/bsky/feed/defs.js.map +1 -1
  133. package/dist/lexicon/types/app/bsky/feed/getQuotes.d.ts +44 -0
  134. package/dist/lexicon/types/app/bsky/feed/getQuotes.d.ts.map +1 -0
  135. package/dist/lexicon/types/app/bsky/feed/getQuotes.js +3 -0
  136. package/dist/lexicon/types/app/bsky/feed/getQuotes.js.map +1 -0
  137. package/dist/lexicon/types/app/bsky/feed/postgate.d.ts +25 -0
  138. package/dist/lexicon/types/app/bsky/feed/postgate.d.ts.map +1 -0
  139. package/dist/lexicon/types/app/bsky/feed/postgate.js +27 -0
  140. package/dist/lexicon/types/app/bsky/feed/postgate.js.map +1 -0
  141. package/dist/lexicon/types/app/bsky/feed/threadgate.d.ts +2 -0
  142. package/dist/lexicon/types/app/bsky/feed/threadgate.d.ts.map +1 -1
  143. package/dist/lexicon/types/app/bsky/feed/threadgate.js.map +1 -1
  144. package/dist/proto/bsky_connect.d.ts +21 -1
  145. package/dist/proto/bsky_connect.d.ts.map +1 -1
  146. package/dist/proto/bsky_connect.js +20 -0
  147. package/dist/proto/bsky_connect.js.map +1 -1
  148. package/dist/proto/bsky_pb.d.ts +96 -0
  149. package/dist/proto/bsky_pb.d.ts.map +1 -1
  150. package/dist/proto/bsky_pb.js +306 -4
  151. package/dist/proto/bsky_pb.js.map +1 -1
  152. package/dist/util/uris.d.ts +12 -0
  153. package/dist/util/uris.d.ts.map +1 -0
  154. package/dist/util/uris.js +34 -0
  155. package/dist/util/uris.js.map +1 -0
  156. package/dist/views/index.d.ts +8 -2
  157. package/dist/views/index.d.ts.map +1 -1
  158. package/dist/views/index.js +83 -39
  159. package/dist/views/index.js.map +1 -1
  160. package/dist/views/types.d.ts +1 -1
  161. package/dist/views/types.d.ts.map +1 -1
  162. package/dist/views/types.js.map +1 -1
  163. package/dist/views/util.d.ts +11 -1
  164. package/dist/views/util.d.ts.map +1 -1
  165. package/dist/views/util.js +19 -8
  166. package/dist/views/util.js.map +1 -1
  167. package/package.json +6 -6
  168. package/proto/bsky.proto +33 -0
  169. package/src/api/app/bsky/actor/getProfiles.ts +10 -1
  170. package/src/api/app/bsky/actor/searchActorsTypeahead.ts +9 -4
  171. package/src/api/app/bsky/feed/getActorLikes.ts +1 -1
  172. package/src/api/app/bsky/feed/getFeed.ts +12 -1
  173. package/src/api/app/bsky/feed/getLikes.ts +1 -1
  174. package/src/api/app/bsky/feed/getPosts.ts +10 -2
  175. package/src/api/app/bsky/feed/getQuotes.ts +105 -0
  176. package/src/api/app/bsky/feed/getRepostedBy.ts +1 -1
  177. package/src/api/app/bsky/feed/searchPosts.ts +1 -1
  178. package/src/api/app/bsky/graph/getFollowers.ts +1 -1
  179. package/src/api/app/bsky/graph/getList.ts +47 -4
  180. package/src/api/app/bsky/notification/listNotifications.ts +32 -6
  181. package/src/api/index.ts +2 -0
  182. package/src/auth-verifier.ts +78 -51
  183. package/src/data-plane/server/db/database-schema.ts +7 -3
  184. package/src/data-plane/server/db/migrations/20240723T220700077Z-quotes-post-aggs.ts +12 -0
  185. package/src/data-plane/server/db/migrations/20240723T220703655Z-quotes.ts +28 -0
  186. package/src/data-plane/server/db/migrations/20240801T193939827Z-post-gate.ts +17 -0
  187. package/src/data-plane/server/db/migrations/20240808T224251220Z-post-gate-flags.ts +25 -0
  188. package/src/data-plane/server/db/migrations/index.ts +4 -0
  189. package/src/data-plane/server/db/tables/post-agg.ts +1 -0
  190. package/src/data-plane/server/db/tables/post-gate.ts +12 -0
  191. package/src/data-plane/server/db/tables/post.ts +3 -0
  192. package/src/data-plane/server/db/tables/quote.ts +15 -0
  193. package/src/data-plane/server/indexing/index.ts +7 -0
  194. package/src/data-plane/server/indexing/plugins/post-gate.ts +104 -0
  195. package/src/data-plane/server/indexing/plugins/post.ts +151 -16
  196. package/src/data-plane/server/indexing/plugins/thread-gate.ts +12 -0
  197. package/src/data-plane/server/routes/index.ts +2 -0
  198. package/src/data-plane/server/routes/interactions.ts +2 -1
  199. package/src/data-plane/server/routes/quotes.ts +32 -0
  200. package/src/data-plane/server/routes/records.ts +11 -1
  201. package/src/data-plane/server/util.ts +0 -8
  202. package/src/hydration/feed.ts +58 -12
  203. package/src/hydration/hydrator.ts +112 -24
  204. package/src/hydration/util.ts +0 -4
  205. package/src/lexicon/index.ts +12 -0
  206. package/src/lexicon/lexicons.ts +145 -0
  207. package/src/lexicon/types/app/bsky/embed/record.ts +19 -0
  208. package/src/lexicon/types/app/bsky/feed/defs.ts +2 -0
  209. package/src/lexicon/types/app/bsky/feed/getQuotes.ts +54 -0
  210. package/src/lexicon/types/app/bsky/feed/postgate.ts +47 -0
  211. package/src/lexicon/types/app/bsky/feed/threadgate.ts +2 -0
  212. package/src/proto/bsky_connect.ts +24 -0
  213. package/src/proto/bsky_pb.ts +289 -0
  214. package/src/util/uris.ts +31 -0
  215. package/src/views/index.ts +90 -35
  216. package/src/views/types.ts +1 -0
  217. package/src/views/util.ts +37 -7
  218. package/tests/__snapshots__/feed-generation.test.ts.snap +37 -0
  219. package/tests/admin/admin-auth.test.ts +15 -8
  220. package/tests/auth.test.ts +2 -1
  221. package/tests/data-plane/__snapshots__/indexing.test.ts.snap +18 -0
  222. package/tests/data-plane/handle-invalidation.test.ts +31 -5
  223. package/tests/data-plane/indexing.test.ts +139 -23
  224. package/tests/data-plane/thread-mutes.test.ts +41 -9
  225. package/tests/feed-generation.test.ts +150 -32
  226. package/tests/postgates.test.ts +186 -0
  227. package/tests/seed/feed-hidden-replies.ts +62 -0
  228. package/tests/seed/postgates.ts +56 -0
  229. package/tests/server.test.ts +1 -1
  230. package/tests/views/__snapshots__/author-feed.test.ts.snap +56 -0
  231. package/tests/views/__snapshots__/block-lists.test.ts.snap +6 -0
  232. package/tests/views/__snapshots__/blocks.test.ts.snap +10 -0
  233. package/tests/views/__snapshots__/list-feed.test.ts.snap +22 -0
  234. package/tests/views/__snapshots__/lists.test.ts.snap +145 -26
  235. package/tests/views/__snapshots__/mute-lists.test.ts.snap +8 -0
  236. package/tests/views/__snapshots__/mutes.test.ts.snap +6 -0
  237. package/tests/views/__snapshots__/posts.test.ts.snap +12 -0
  238. package/tests/views/__snapshots__/quotes.test.ts.snap +399 -0
  239. package/tests/views/__snapshots__/starter-packs.test.ts.snap +245 -4
  240. package/tests/views/__snapshots__/thread.test.ts.snap +50 -0
  241. package/tests/views/__snapshots__/timeline.test.ts.snap +170 -0
  242. package/tests/views/account-deactivation.test.ts +8 -2
  243. package/tests/views/actor-likes.test.ts +27 -6
  244. package/tests/views/actor-search.test.ts +5 -1
  245. package/tests/views/author-feed.test.ts +76 -21
  246. package/tests/views/block-lists.test.ts +201 -40
  247. package/tests/views/blocks.test.ts +245 -46
  248. package/tests/views/feed-hidden-replies.test.ts +246 -0
  249. package/tests/views/feed-view-post.test.ts +501 -0
  250. package/tests/views/follows.test.ts +133 -22
  251. package/tests/views/known-followers.test.ts +43 -7
  252. package/tests/views/labeler-service.test.ts +36 -6
  253. package/tests/views/likes.test.ts +8 -5
  254. package/tests/views/list-feed.test.ts +25 -4
  255. package/tests/views/lists.test.ts +73 -31
  256. package/tests/views/mute-lists.test.ts +101 -29
  257. package/tests/views/mutes.test.ts +77 -17
  258. package/tests/views/notifications.test.ts +141 -25
  259. package/tests/views/posts.test.ts +13 -2
  260. package/tests/views/profile.test.ts +37 -11
  261. package/tests/views/quotes.test.ts +105 -0
  262. package/tests/views/reposts.test.ts +31 -5
  263. package/tests/views/starter-packs.test.ts +83 -3
  264. package/tests/views/suggested-follows.test.ts +31 -5
  265. package/tests/views/suggestions.test.ts +37 -6
  266. package/tests/views/thread.test.ts +121 -20
  267. package/tests/views/threadgating.test.ts +128 -22
  268. package/tests/views/timeline.test.ts +67 -14
@@ -1,7 +1,7 @@
1
1
  import { BlobRef } from '@atproto/lexicon';
2
2
  import { Record as PostRecord } from '../lexicon/types/app/bsky/feed/post';
3
3
  import { Record as GateRecord } from '../lexicon/types/app/bsky/feed/threadgate';
4
- export declare const creatorFromUri: (uri: string) => string;
4
+ import { Record as PostgateRecord } from '../lexicon/types/app/bsky/feed/postgate';
5
5
  export declare const parseThreadGate: (replierDid: string, ownerDid: string, rootPost: PostRecord | null, gate: GateRecord | null) => ParsedThreadGate;
6
6
  type ParsedThreadGate = {
7
7
  canReply?: boolean;
@@ -10,5 +10,15 @@ type ParsedThreadGate = {
10
10
  allowListUris?: string[];
11
11
  };
12
12
  export declare const cidFromBlobJson: (json: BlobRef) => string;
13
+ export declare const parsePostgate: ({ gate, viewerDid, authorDid, }: {
14
+ gate: PostgateRecord | undefined;
15
+ viewerDid: string | undefined;
16
+ authorDid: string;
17
+ }) => ParsedPostgate;
18
+ type ParsedPostgate = {
19
+ embeddingRules: {
20
+ canEmbed: boolean;
21
+ };
22
+ };
13
23
  export {};
14
24
  //# sourceMappingURL=util.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../src/views/util.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAA;AAC1C,OAAO,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,qCAAqC,CAAA;AAC1E,OAAO,EACL,MAAM,IAAI,UAAU,EAIrB,MAAM,2CAA2C,CAAA;AAGlD,eAAO,MAAM,cAAc,QAAS,MAAM,KAAG,MAE5C,CAAA;AAED,eAAO,MAAM,eAAe,eACd,MAAM,YACR,MAAM,YACN,UAAU,GAAG,IAAI,QACrB,UAAU,GAAG,IAAI,KACtB,gBAyBF,CAAA;AAED,KAAK,gBAAgB,GAAG;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;CACzB,CAAA;AAED,eAAO,MAAM,eAAe,SAAU,OAAO,WAS5C,CAAA"}
1
+ {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../src/views/util.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAA;AAC1C,OAAO,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,qCAAqC,CAAA;AAC1E,OAAO,EACL,MAAM,IAAI,UAAU,EAIrB,MAAM,2CAA2C,CAAA;AAClD,OAAO,EACL,MAAM,IAAI,cAAc,EAEzB,MAAM,yCAAyC,CAAA;AAGhD,eAAO,MAAM,eAAe,eACd,MAAM,YACR,MAAM,YACN,UAAU,GAAG,IAAI,QACrB,UAAU,GAAG,IAAI,KACtB,gBAyBF,CAAA;AAED,KAAK,gBAAgB,GAAG;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;CACzB,CAAA;AAED,eAAO,MAAM,eAAe,SAAU,OAAO,WAS5C,CAAA;AAED,eAAO,MAAM,aAAa,oCAIvB;IACD,IAAI,EAAE,cAAc,GAAG,SAAS,CAAA;IAChC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAA;IAC7B,SAAS,EAAE,MAAM,CAAA;CAClB,KAAG,cAeH,CAAA;AAED,KAAK,cAAc,GAAG;IACpB,cAAc,EAAE;QACd,QAAQ,EAAE,OAAO,CAAA;KAClB,CAAA;CACF,CAAA"}
@@ -1,14 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.cidFromBlobJson = exports.parseThreadGate = exports.creatorFromUri = void 0;
4
- const syntax_1 = require("@atproto/syntax");
3
+ exports.parsePostgate = exports.cidFromBlobJson = exports.parseThreadGate = void 0;
5
4
  const lexicon_1 = require("@atproto/lexicon");
6
5
  const threadgate_1 = require("../lexicon/types/app/bsky/feed/threadgate");
6
+ const postgate_1 = require("../lexicon/types/app/bsky/feed/postgate");
7
7
  const facet_1 = require("../lexicon/types/app/bsky/richtext/facet");
8
- const creatorFromUri = (uri) => {
9
- return new syntax_1.AtUri(uri).hostname;
10
- };
11
- exports.creatorFromUri = creatorFromUri;
12
8
  const parseThreadGate = (replierDid, ownerDid, rootPost, gate) => {
13
9
  if (replierDid === ownerDid) {
14
10
  return { canReply: true };
@@ -17,8 +13,8 @@ const parseThreadGate = (replierDid, ownerDid, rootPost, gate) => {
17
13
  if (!gate || !gate.allow) {
18
14
  return { canReply: true };
19
15
  }
20
- const allowMentions = !!gate.allow.find(threadgate_1.isMentionRule);
21
- const allowFollowing = !!gate.allow.find(threadgate_1.isFollowingRule);
16
+ const allowMentions = gate.allow.some(threadgate_1.isMentionRule);
17
+ const allowFollowing = gate.allow.some(threadgate_1.isFollowingRule);
22
18
  const allowListUris = gate.allow?.filter(threadgate_1.isListRule).map((item) => item.list);
23
19
  // check mentions first since it's quick and synchronous
24
20
  if (allowMentions) {
@@ -43,4 +39,19 @@ const cidFromBlobJson = (json) => {
43
39
  return (json['cid'] ?? '');
44
40
  };
45
41
  exports.cidFromBlobJson = cidFromBlobJson;
42
+ const parsePostgate = ({ gate, viewerDid, authorDid, }) => {
43
+ if (viewerDid === authorDid) {
44
+ return { embeddingRules: { canEmbed: true } };
45
+ }
46
+ // default state is unset, allow everyone
47
+ if (!gate || !gate.embeddingRules) {
48
+ return { embeddingRules: { canEmbed: true } };
49
+ }
50
+ const disabled = gate.embeddingRules.some(postgate_1.isDisableRule);
51
+ if (disabled) {
52
+ return { embeddingRules: { canEmbed: false } };
53
+ }
54
+ return { embeddingRules: { canEmbed: true } };
55
+ };
56
+ exports.parsePostgate = parsePostgate;
46
57
  //# sourceMappingURL=util.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"util.js","sourceRoot":"","sources":["../../src/views/util.ts"],"names":[],"mappings":";;;AAAA,4CAAuC;AACvC,8CAA0C;AAE1C,0EAKkD;AAClD,oEAAoE;AAE7D,MAAM,cAAc,GAAG,CAAC,GAAW,EAAU,EAAE;IACpD,OAAO,IAAI,cAAK,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAA;AAChC,CAAC,CAAA;AAFY,QAAA,cAAc,kBAE1B;AAEM,MAAM,eAAe,GAAG,CAC7B,UAAkB,EAClB,QAAgB,EAChB,QAA2B,EAC3B,IAAuB,EACL,EAAE;IACpB,IAAI,UAAU,KAAK,QAAQ,EAAE,CAAC;QAC5B,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAA;IAC3B,CAAC;IACD,yGAAyG;IACzG,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QACzB,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAA;IAC3B,CAAC;IAED,MAAM,aAAa,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,0BAAa,CAAC,CAAA;IACtD,MAAM,cAAc,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,4BAAe,CAAC,CAAA;IACzD,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,uBAAU,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAE7E,wDAAwD;IACxD,IAAI,aAAa,EAAE,CAAC;QAClB,MAAM,WAAW,GAAG,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE;YACnD,OAAO,KAAK,CAAC,QAAQ,CAAC,IAAI,CACxB,CAAC,IAAI,EAAE,EAAE,CAAC,IAAA,iBAAS,EAAC,IAAI,CAAC,IAAI,IAAI,CAAC,GAAG,KAAK,UAAU,CACrD,CAAA;QACH,CAAC,CAAC,CAAA;QACF,IAAI,WAAW,EAAE,CAAC;YAChB,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,aAAa,EAAE,cAAc,EAAE,aAAa,EAAE,CAAA;QACzE,CAAC;IACH,CAAC;IACD,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,aAAa,EAAE,CAAA;AACzD,CAAC,CAAA;AA9BY,QAAA,eAAe,mBA8B3B;AASM,MAAM,eAAe,GAAG,CAAC,IAAa,EAAE,EAAE;IAC/C,IAAI,IAAI,YAAY,iBAAO,EAAE,CAAC;QAC5B,OAAO,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAA;IAC5B,CAAC;IACD,oGAAoG;IACpG,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,MAAM,EAAE,CAAC;QAC7B,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,CAAW,CAAA;IACjD,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAW,CAAA;AACtC,CAAC,CAAA;AATY,QAAA,eAAe,mBAS3B"}
1
+ {"version":3,"file":"util.js","sourceRoot":"","sources":["../../src/views/util.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atproto/bsky",
3
- "version": "0.0.75",
3
+ "version": "0.0.77",
4
4
  "license": "MIT",
5
5
  "description": "Reference implementation of app.bsky App View (Bluesky API)",
6
6
  "keywords": [
@@ -40,14 +40,14 @@
40
40
  "structured-headers": "^1.0.1",
41
41
  "typed-emitter": "^2.1.0",
42
42
  "uint8arrays": "3.0.0",
43
- "@atproto/api": "^0.13.1",
44
- "@atproto/crypto": "^0.4.0",
43
+ "@atproto/api": "^0.13.2",
45
44
  "@atproto/common": "^0.4.1",
45
+ "@atproto/crypto": "^0.4.0",
46
46
  "@atproto/identity": "^0.4.0",
47
47
  "@atproto/lexicon": "^0.4.1",
48
48
  "@atproto/repo": "^0.4.2",
49
49
  "@atproto/syntax": "^0.3.0",
50
- "@atproto/xrpc-server": "^0.6.1"
50
+ "@atproto/xrpc-server": "^0.6.2"
51
51
  },
52
52
  "devDependencies": {
53
53
  "@bufbuild/buf": "^1.28.1",
@@ -62,9 +62,9 @@
62
62
  "axios": "^0.27.2",
63
63
  "jest": "^28.1.2",
64
64
  "ts-node": "^10.8.2",
65
- "@atproto/api": "^0.13.1",
65
+ "@atproto/api": "^0.13.2",
66
66
  "@atproto/lex-cli": "^0.5.0",
67
- "@atproto/pds": "^0.4.49",
67
+ "@atproto/pds": "^0.4.52",
68
68
  "@atproto/xrpc": "^0.6.0"
69
69
  },
70
70
  "scripts": {
package/proto/bsky.proto CHANGED
@@ -79,6 +79,9 @@ message PostRecordMeta {
79
79
  bool violates_thread_gate = 1;
80
80
  bool has_media = 2;
81
81
  bool is_reply = 3;
82
+ bool violates_embedding_rules = 4;
83
+ bool has_post_gate = 5;
84
+ bool has_thread_gate = 6;
82
85
  }
83
86
 
84
87
  message GetPostRecordsRequest {
@@ -122,6 +125,14 @@ message GetThreadGateRecordsResponse {
122
125
  repeated Record records = 1;
123
126
  }
124
127
 
128
+ message GetPostGateRecordsRequest {
129
+ repeated string uris = 1;
130
+ }
131
+
132
+ message GetPostGateRecordsResponse {
133
+ repeated Record records = 1;
134
+ }
135
+
125
136
  message GetLabelerRecordsRequest {
126
137
  repeated string uris = 1;
127
138
  }
@@ -249,6 +260,23 @@ message GetActorLikesResponse {
249
260
  string cursor = 2;
250
261
  }
251
262
 
263
+ //
264
+ // Quotes
265
+ //
266
+
267
+ message GetQuotesBySubjectRequest {
268
+ RecordRef subject = 1;
269
+ int32 limit = 2;
270
+ string cursor = 3;
271
+ }
272
+
273
+ message GetQuotesBySubjectResponse {
274
+ repeated RecordRef refs = 1;
275
+ string cursor = 2;
276
+ }
277
+
278
+ // - return post uris that quote the given subject uri
279
+
252
280
  //
253
281
  // Interactions
254
282
  //
@@ -260,6 +288,7 @@ message GetInteractionCountsResponse {
260
288
  repeated int32 likes = 1;
261
289
  repeated int32 reposts = 2;
262
290
  repeated int32 replies = 3;
291
+ repeated int32 quotes = 4;
263
292
  }
264
293
 
265
294
  message GetCountsForUsersRequest {
@@ -1068,6 +1097,7 @@ service Service {
1068
1097
  rpc GetActorChatDeclarationRecords(GetActorChatDeclarationRecordsRequest) returns (GetActorChatDeclarationRecordsResponse);
1069
1098
  rpc GetRepostRecords(GetRepostRecordsRequest) returns (GetRepostRecordsResponse);
1070
1099
  rpc GetThreadGateRecords(GetThreadGateRecordsRequest) returns (GetThreadGateRecordsResponse);
1100
+ rpc GetPostGateRecords(GetPostGateRecordsRequest) returns (GetPostGateRecordsResponse);
1071
1101
  rpc GetLabelerRecords(GetLabelerRecordsRequest) returns (GetLabelerRecordsResponse);
1072
1102
  rpc GetStarterPackRecords(GetStarterPackRecordsRequest) returns (GetStarterPackRecordsResponse);
1073
1103
 
@@ -1087,6 +1117,9 @@ service Service {
1087
1117
  rpc GetRepostsByActorAndSubjects(GetRepostsByActorAndSubjectsRequest) returns (GetRepostsByActorAndSubjectsResponse);
1088
1118
  rpc GetActorReposts(GetActorRepostsRequest) returns (GetActorRepostsResponse);
1089
1119
 
1120
+ // Quotes
1121
+ rpc GetQuotesBySubject(GetQuotesBySubjectRequest) returns (GetQuotesBySubjectResponse);
1122
+
1090
1123
  // Interaction Counts
1091
1124
  rpc GetInteractionCounts(GetInteractionCountsRequest) returns (GetInteractionCountsResponse);
1092
1125
  rpc GetCountsForUsers(GetCountsForUsersRequest) returns (GetCountsForUsersResponse);
@@ -10,11 +10,20 @@ import {
10
10
  Hydrator,
11
11
  } from '../../../../hydration/hydrator'
12
12
  import { Views } from '../../../../views'
13
+ import { ids } from '../../../../lexicon/lexicons'
13
14
 
14
15
  export default function (server: Server, ctx: AppContext) {
15
16
  const getProfile = createPipeline(skeleton, hydration, noRules, presentation)
16
17
  server.app.bsky.actor.getProfiles({
17
- auth: ctx.authVerifier.standardOptional,
18
+ auth: ctx.authVerifier.standardOptionalParameterized({
19
+ lxmCheck: (method) => {
20
+ if (!method) return false
21
+ return (
22
+ method === ids.AppBskyActorGetProfiles ||
23
+ method.startsWith('chat.bsky.')
24
+ )
25
+ },
26
+ }),
18
27
  handler: async ({ auth, params, req }) => {
19
28
  const viewer = auth.credentials.iss
20
29
  const labelers = ctx.reqLabelers(req)
@@ -82,10 +82,15 @@ const hydration = async (
82
82
  }
83
83
 
84
84
  const noBlocks = (inputs: RulesFnInput<Context, Params, Skeleton>) => {
85
- const { ctx, skeleton, hydration } = inputs
86
- skeleton.dids = skeleton.dids.filter(
87
- (did) => !ctx.views.viewerBlockExists(did, hydration),
88
- )
85
+ const { ctx, skeleton, hydration, params } = inputs
86
+ skeleton.dids = skeleton.dids.filter((did) => {
87
+ const actor = hydration.actors?.get(did)
88
+ if (!actor) return false
89
+ // Always display exact matches so that users can find profiles that they have blocked
90
+ const term = (params.q ?? params.term ?? '').toLowerCase()
91
+ const isExactMatch = actor.handle?.toLowerCase() === term
92
+ return isExactMatch || !ctx.views.viewerBlockExists(did, hydration)
93
+ })
89
94
  return skeleton
90
95
  }
91
96
 
@@ -13,7 +13,7 @@ import {
13
13
  import { Views } from '../../../../views'
14
14
  import { DataPlaneClient } from '../../../../data-plane'
15
15
  import { parseString } from '../../../../hydration/util'
16
- import { creatorFromUri } from '../../../../views/util'
16
+ import { uriToDid as creatorFromUri } from '../../../../util/uris'
17
17
  import { FeedItem } from '../../../../hydration/feed'
18
18
 
19
19
  export default function (server: Server, ctx: AppContext) {
@@ -29,6 +29,7 @@ import {
29
29
  unpackIdentityServices,
30
30
  } from '../../../../data-plane'
31
31
  import { resHeaders } from '../../../util'
32
+ import { ids } from '../../../../lexicon/lexicons'
32
33
 
33
34
  export default function (server: Server, ctx: AppContext) {
34
35
  const getFeed = createPipeline(
@@ -38,7 +39,17 @@ export default function (server: Server, ctx: AppContext) {
38
39
  presentation,
39
40
  )
40
41
  server.app.bsky.feed.getFeed({
41
- auth: ctx.authVerifier.standardOptionalAnyAud,
42
+ auth: ctx.authVerifier.standardOptionalParameterized({
43
+ lxmCheck: (method) => {
44
+ return (
45
+ method !== undefined &&
46
+ [ids.AppBskyFeedGetFeedSkeleton, ids.AppBskyFeedGetFeed].includes(
47
+ method,
48
+ )
49
+ )
50
+ },
51
+ skipAudCheck: true,
52
+ }),
42
53
  handler: async ({ params, auth, req }) => {
43
54
  const viewer = auth.credentials.iss
44
55
  const labelers = ctx.reqLabelers(req)
@@ -11,7 +11,7 @@ import {
11
11
  } from '../../../../hydration/hydrator'
12
12
  import { Views } from '../../../../views'
13
13
  import { parseString } from '../../../../hydration/util'
14
- import { creatorFromUri } from '../../../../views/util'
14
+ import { uriToDid as creatorFromUri } from '../../../../util/uris'
15
15
  import { clearlyBadCursor, resHeaders } from '../../../util'
16
16
  import { InvalidRequestError } from '@atproto/xrpc-server'
17
17
 
@@ -9,13 +9,21 @@ import {
9
9
  Hydrator,
10
10
  } from '../../../../hydration/hydrator'
11
11
  import { Views } from '../../../../views'
12
- import { creatorFromUri } from '../../../../views/util'
12
+ import { uriToDid as creatorFromUri } from '../../../../util/uris'
13
13
  import { resHeaders } from '../../../util'
14
+ import { ids } from '../../../../lexicon/lexicons'
14
15
 
15
16
  export default function (server: Server, ctx: AppContext) {
16
17
  const getPosts = createPipeline(skeleton, hydration, noBlocks, presentation)
17
18
  server.app.bsky.feed.getPosts({
18
- auth: ctx.authVerifier.standardOptional,
19
+ auth: ctx.authVerifier.standardOptionalParameterized({
20
+ lxmCheck: (method) => {
21
+ if (!method) return false
22
+ return (
23
+ method === ids.AppBskyFeedGetPosts || method.startsWith('chat.bsky.')
24
+ )
25
+ },
26
+ }),
19
27
  handler: async ({ params, auth, req }) => {
20
28
  const viewer = auth.credentials.iss
21
29
  const labelers = ctx.reqLabelers(req)
@@ -0,0 +1,105 @@
1
+ import { Server } from '../../../../lexicon'
2
+ import AppContext from '../../../../context'
3
+ import { createPipeline } from '../../../../pipeline'
4
+ import { clearlyBadCursor, resHeaders } from '../../../util'
5
+ import {
6
+ HydrateCtx,
7
+ HydrationState,
8
+ Hydrator,
9
+ } from '../../../../hydration/hydrator'
10
+ import { Views } from '../../../../views'
11
+ import { mapDefined } from '@atproto/common'
12
+ import { QueryParams } from '../../../../lexicon/types/app/bsky/feed/getQuotes'
13
+ import { ItemRef, parseString } from '../../../../hydration/util'
14
+
15
+ export default function (server: Server, ctx: AppContext) {
16
+ const getQuotes = createPipeline(skeleton, hydration, noBlocks, presentation)
17
+ server.app.bsky.feed.getQuotes({
18
+ auth: ctx.authVerifier.standardOptional,
19
+ handler: async ({ params, auth, req }) => {
20
+ const { viewer, includeTakedowns } = ctx.authVerifier.parseCreds(auth)
21
+ const labelers = ctx.reqLabelers(req)
22
+ const hydrateCtx = await ctx.hydrator.createContext({
23
+ labelers,
24
+ viewer,
25
+ includeTakedowns,
26
+ })
27
+ const result = await getQuotes({ ...params, hydrateCtx }, ctx)
28
+ return {
29
+ encoding: 'application/json',
30
+ body: result,
31
+ headers: resHeaders({ labelers: hydrateCtx.labelers }),
32
+ }
33
+ },
34
+ })
35
+ }
36
+
37
+ const skeleton = async (inputs: {
38
+ ctx: Context
39
+ params: Params
40
+ }): Promise<Skeleton> => {
41
+ const { ctx, params } = inputs
42
+ if (clearlyBadCursor(params.cursor)) {
43
+ return { refs: [] }
44
+ }
45
+ const quotesRes = await ctx.hydrator.dataplane.getQuotesBySubject({
46
+ subject: { uri: params.uri, cid: params.cid },
47
+ cursor: params.cursor,
48
+ limit: params.limit,
49
+ })
50
+ return {
51
+ refs: quotesRes.refs,
52
+ cursor: parseString(quotesRes.cursor),
53
+ }
54
+ }
55
+
56
+ const hydration = async (inputs: {
57
+ ctx: Context
58
+ params: Params
59
+ skeleton: Skeleton
60
+ }) => {
61
+ const { ctx, params, skeleton } = inputs
62
+ return await ctx.hydrator.hydratePosts(skeleton.refs, params.hydrateCtx)
63
+ }
64
+
65
+ const noBlocks = (inputs: {
66
+ ctx: Context
67
+ skeleton: Skeleton
68
+ hydration: HydrationState
69
+ }) => {
70
+ const { ctx, skeleton, hydration } = inputs
71
+ skeleton.refs = skeleton.refs.filter((ref) => {
72
+ return !ctx.views.viewerBlockExists(ref.uri, hydration)
73
+ })
74
+ return skeleton
75
+ }
76
+
77
+ const presentation = (inputs: {
78
+ ctx: Context
79
+ params: Params
80
+ skeleton: Skeleton
81
+ hydration: HydrationState
82
+ }) => {
83
+ const { ctx, params, skeleton, hydration } = inputs
84
+ const postViews = mapDefined(skeleton.refs, (ref) => {
85
+ return ctx.views.post(ref.uri, hydration)
86
+ })
87
+ return {
88
+ posts: postViews,
89
+ cursor: skeleton.cursor,
90
+ uri: params.uri,
91
+ cid: params.cid,
92
+ }
93
+ }
94
+
95
+ type Context = {
96
+ hydrator: Hydrator
97
+ views: Views
98
+ }
99
+
100
+ type Params = QueryParams & { hydrateCtx: HydrateCtx }
101
+
102
+ type Skeleton = {
103
+ refs: ItemRef[]
104
+ cursor?: string
105
+ }
@@ -10,7 +10,7 @@ import {
10
10
  } from '../../../../hydration/hydrator'
11
11
  import { Views } from '../../../../views'
12
12
  import { parseString } from '../../../../hydration/util'
13
- import { creatorFromUri } from '../../../../views/util'
13
+ import { uriToDid as creatorFromUri } from '../../../../util/uris'
14
14
  import { clearlyBadCursor, resHeaders } from '../../../util'
15
15
 
16
16
  export default function (server: Server, ctx: AppContext) {
@@ -14,7 +14,7 @@ import { HydrateCtx, Hydrator } from '../../../../hydration/hydrator'
14
14
  import { Views } from '../../../../views'
15
15
  import { DataPlaneClient } from '../../../../data-plane'
16
16
  import { parseString } from '../../../../hydration/util'
17
- import { creatorFromUri } from '../../../../views/util'
17
+ import { uriToDid as creatorFromUri } from '../../../../util/uris'
18
18
  import { resHeaders } from '../../../util'
19
19
 
20
20
  export default function (server: Server, ctx: AppContext) {
@@ -10,7 +10,7 @@ import {
10
10
  SkeletonFnInput,
11
11
  createPipeline,
12
12
  } from '../../../../pipeline'
13
- import { didFromUri } from '../../../../hydration/util'
13
+ import { uriToDid as didFromUri } from '../../../../util/uris'
14
14
  import {
15
15
  HydrateCtx,
16
16
  Hydrator,
@@ -6,21 +6,23 @@ import AppContext from '../../../../context'
6
6
  import {
7
7
  createPipeline,
8
8
  HydrationFnInput,
9
- noRules,
10
9
  PresentationFnInput,
10
+ RulesFnInput,
11
11
  SkeletonFnInput,
12
12
  } from '../../../../pipeline'
13
13
  import {
14
14
  HydrateCtx,
15
+ HydrationState,
15
16
  Hydrator,
16
- mergeStates,
17
+ mergeManyStates,
17
18
  } from '../../../../hydration/hydrator'
18
19
  import { Views } from '../../../../views'
19
20
  import { clearlyBadCursor, resHeaders } from '../../../util'
20
21
  import { ListItemInfo } from '../../../../proto/bsky_pb'
22
+ import { uriToDid as didFromUri } from '../../../../util/uris'
21
23
 
22
24
  export default function (server: Server, ctx: AppContext) {
23
- const getList = createPipeline(skeleton, hydration, noRules, presentation)
25
+ const getList = createPipeline(skeleton, hydration, noBlocks, presentation)
24
26
  server.app.bsky.graph.getList({
25
27
  auth: ctx.authVerifier.standardOptional,
26
28
  handler: async ({ params, auth, req }) => {
@@ -68,7 +70,23 @@ const hydration = async (
68
70
  params.hydrateCtx,
69
71
  ),
70
72
  ])
71
- return mergeStates(listState, profileState)
73
+ const bidirectionalBlocks = await maybeGetBlocksForReferenceList({
74
+ ctx,
75
+ params,
76
+ skeleton,
77
+ listState,
78
+ })
79
+ return mergeManyStates(listState, profileState, { bidirectionalBlocks })
80
+ }
81
+
82
+ const noBlocks = (input: RulesFnInput<Context, Params, SkeletonState>) => {
83
+ const { skeleton, hydration } = input
84
+ const creator = didFromUri(skeleton.listUri)
85
+ const blocks = hydration.bidirectionalBlocks?.get(creator)
86
+ skeleton.listitems = skeleton.listitems.filter(({ did }) => {
87
+ return !blocks?.get(did)
88
+ })
89
+ return skeleton
72
90
  }
73
91
 
74
92
  const presentation = (
@@ -88,6 +106,31 @@ const presentation = (
88
106
  return { list, items, cursor }
89
107
  }
90
108
 
109
+ const maybeGetBlocksForReferenceList = async (input: {
110
+ ctx: Context
111
+ listState: HydrationState
112
+ skeleton: SkeletonState
113
+ params: Params
114
+ }) => {
115
+ const { ctx, params, listState, skeleton } = input
116
+ const { listitems } = skeleton
117
+ const { list } = params
118
+ const listRecord = listState.lists?.get(list)
119
+ const creator = didFromUri(list)
120
+ if (
121
+ listRecord?.record.purpose !== 'app.bsky.graph.defs#referencelist' ||
122
+ params.hydrateCtx.viewer === creator
123
+ ) {
124
+ return
125
+ }
126
+ const pairs: Map<string, string[]> = new Map()
127
+ pairs.set(
128
+ creator,
129
+ listitems.map(({ did }) => did),
130
+ )
131
+ return await ctx.hydrator.hydrateBidirectionalBlocks(pairs)
132
+ }
133
+
91
134
  type Context = {
92
135
  hydrator: Hydrator
93
136
  views: Views
@@ -2,6 +2,7 @@ import { InvalidRequestError } from '@atproto/xrpc-server'
2
2
  import { mapDefined } from '@atproto/common'
3
3
  import { Server } from '../../../../lexicon'
4
4
  import { QueryParams } from '../../../../lexicon/types/app/bsky/notification/listNotifications'
5
+ import { isRecord as isPostRecord } from '../../../../lexicon/types/app/bsky/feed/post'
5
6
  import AppContext from '../../../../context'
6
7
  import {
7
8
  createPipeline,
@@ -13,7 +14,7 @@ import {
13
14
  import { HydrateCtx, Hydrator } from '../../../../hydration/hydrator'
14
15
  import { Views } from '../../../../views'
15
16
  import { Notification } from '../../../../proto/bsky_pb'
16
- import { didFromUri } from '../../../../hydration/util'
17
+ import { uriToDid as didFromUri } from '../../../../util/uris'
17
18
  import { clearlyBadCursor, resHeaders } from '../../../util'
18
19
 
19
20
  export default function (server: Server, ctx: AppContext) {
@@ -90,13 +91,38 @@ const hydration = async (
90
91
  const noBlockOrMutes = (
91
92
  input: RulesFnInput<Context, Params, SkeletonState>,
92
93
  ) => {
93
- const { skeleton, hydration, ctx } = input
94
+ const { skeleton, hydration, ctx, params } = input
94
95
  skeleton.notifs = skeleton.notifs.filter((item) => {
95
96
  const did = didFromUri(item.uri)
96
- return (
97
- !ctx.views.viewerBlockExists(did, hydration) &&
98
- !ctx.views.viewerMuteExists(did, hydration)
99
- )
97
+ if (
98
+ ctx.views.viewerBlockExists(did, hydration) ||
99
+ ctx.views.viewerMuteExists(did, hydration)
100
+ ) {
101
+ return false
102
+ }
103
+ // Filter out hidden replies only if the viewer owns
104
+ // the threadgate and they hid the reply.
105
+ if (item.reason === 'reply') {
106
+ const post = hydration.posts?.get(item.uri)
107
+ if (post) {
108
+ const rootPostUri = isPostRecord(post.record)
109
+ ? post.record.reply?.root.uri
110
+ : undefined
111
+ const isRootPostByViewer =
112
+ rootPostUri && didFromUri(rootPostUri) === params.hydrateCtx?.viewer
113
+ const isHiddenReply = isRootPostByViewer
114
+ ? ctx.views.replyIsHiddenByThreadgate(
115
+ item.uri,
116
+ rootPostUri,
117
+ hydration,
118
+ )
119
+ : false
120
+ if (isHiddenReply) {
121
+ return false
122
+ }
123
+ }
124
+ }
125
+ return true
100
126
  })
101
127
  return skeleton
102
128
  }
package/src/api/index.ts CHANGED
@@ -13,6 +13,7 @@ import getPostThread from './app/bsky/feed/getPostThread'
13
13
  import getPosts from './app/bsky/feed/getPosts'
14
14
  import searchPosts from './app/bsky/feed/searchPosts'
15
15
  import getActorLikes from './app/bsky/feed/getActorLikes'
16
+ import getQuotes from './app/bsky/feed/getQuotes'
16
17
  import getProfile from './app/bsky/actor/getProfile'
17
18
  import getProfiles from './app/bsky/actor/getProfiles'
18
19
  import getRepostedBy from './app/bsky/feed/getRepostedBy'
@@ -72,6 +73,7 @@ export default function (server: Server, ctx: AppContext) {
72
73
  getFeedGenerators(server, ctx)
73
74
  getLikes(server, ctx)
74
75
  getListFeed(server, ctx)
76
+ getQuotes(server, ctx)
75
77
  getPostThread(server, ctx)
76
78
  getPosts(server, ctx)
77
79
  searchPosts(server, ctx)