@atproto/bsky 0.0.76 → 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 (219) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/dist/api/app/bsky/feed/getActorLikes.js +2 -2
  3. package/dist/api/app/bsky/feed/getActorLikes.js.map +1 -1
  4. package/dist/api/app/bsky/feed/getLikes.js +6 -6
  5. package/dist/api/app/bsky/feed/getLikes.js.map +1 -1
  6. package/dist/api/app/bsky/feed/getPosts.js +4 -4
  7. package/dist/api/app/bsky/feed/getPosts.js.map +1 -1
  8. package/dist/api/app/bsky/feed/getQuotes.d.ts +4 -0
  9. package/dist/api/app/bsky/feed/getQuotes.d.ts.map +1 -0
  10. package/dist/api/app/bsky/feed/getQuotes.js +67 -0
  11. package/dist/api/app/bsky/feed/getQuotes.js.map +1 -0
  12. package/dist/api/app/bsky/feed/getRepostedBy.js +6 -6
  13. package/dist/api/app/bsky/feed/getRepostedBy.js.map +1 -1
  14. package/dist/api/app/bsky/feed/searchPosts.js +4 -4
  15. package/dist/api/app/bsky/feed/searchPosts.js.map +1 -1
  16. package/dist/api/app/bsky/graph/getFollowers.js +8 -8
  17. package/dist/api/app/bsky/graph/getFollowers.js.map +1 -1
  18. package/dist/api/app/bsky/graph/getList.js +3 -3
  19. package/dist/api/app/bsky/graph/getList.js.map +1 -1
  20. package/dist/api/app/bsky/notification/listNotifications.d.ts.map +1 -1
  21. package/dist/api/app/bsky/notification/listNotifications.js +29 -8
  22. package/dist/api/app/bsky/notification/listNotifications.js.map +1 -1
  23. package/dist/api/index.d.ts.map +1 -1
  24. package/dist/api/index.js +2 -0
  25. package/dist/api/index.js.map +1 -1
  26. package/dist/data-plane/server/db/database-schema.d.ts +4 -2
  27. package/dist/data-plane/server/db/database-schema.d.ts.map +1 -1
  28. package/dist/data-plane/server/db/migrations/20240723T220700077Z-quotes-post-aggs.d.ts +4 -0
  29. package/dist/data-plane/server/db/migrations/20240723T220700077Z-quotes-post-aggs.d.ts.map +1 -0
  30. package/dist/data-plane/server/db/migrations/20240723T220700077Z-quotes-post-aggs.js +15 -0
  31. package/dist/data-plane/server/db/migrations/20240723T220700077Z-quotes-post-aggs.js.map +1 -0
  32. package/dist/data-plane/server/db/migrations/20240723T220703655Z-quotes.d.ts +4 -0
  33. package/dist/data-plane/server/db/migrations/20240723T220703655Z-quotes.d.ts.map +1 -0
  34. package/dist/data-plane/server/db/migrations/20240723T220703655Z-quotes.js +30 -0
  35. package/dist/data-plane/server/db/migrations/20240723T220703655Z-quotes.js.map +1 -0
  36. package/dist/data-plane/server/db/migrations/20240801T193939827Z-post-gate.d.ts +4 -0
  37. package/dist/data-plane/server/db/migrations/20240801T193939827Z-post-gate.d.ts.map +1 -0
  38. package/dist/data-plane/server/db/migrations/20240801T193939827Z-post-gate.js +20 -0
  39. package/dist/data-plane/server/db/migrations/20240801T193939827Z-post-gate.js.map +1 -0
  40. package/dist/data-plane/server/db/migrations/20240808T224251220Z-post-gate-flags.d.ts +4 -0
  41. package/dist/data-plane/server/db/migrations/20240808T224251220Z-post-gate-flags.d.ts.map +1 -0
  42. package/dist/data-plane/server/db/migrations/20240808T224251220Z-post-gate-flags.js +28 -0
  43. package/dist/data-plane/server/db/migrations/20240808T224251220Z-post-gate-flags.js.map +1 -0
  44. package/dist/data-plane/server/db/migrations/index.d.ts +4 -0
  45. package/dist/data-plane/server/db/migrations/index.d.ts.map +1 -1
  46. package/dist/data-plane/server/db/migrations/index.js +5 -1
  47. package/dist/data-plane/server/db/migrations/index.js.map +1 -1
  48. package/dist/data-plane/server/db/tables/post-agg.d.ts +1 -0
  49. package/dist/data-plane/server/db/tables/post-agg.d.ts.map +1 -1
  50. package/dist/data-plane/server/db/tables/post-gate.d.ts +14 -0
  51. package/dist/data-plane/server/db/tables/post-gate.d.ts.map +1 -0
  52. package/dist/data-plane/server/db/tables/post-gate.js +4 -0
  53. package/dist/data-plane/server/db/tables/post-gate.js.map +1 -0
  54. package/dist/data-plane/server/db/tables/post.d.ts +3 -0
  55. package/dist/data-plane/server/db/tables/post.d.ts.map +1 -1
  56. package/dist/data-plane/server/db/tables/quote.d.ts +16 -0
  57. package/dist/data-plane/server/db/tables/quote.d.ts.map +1 -0
  58. package/dist/data-plane/server/db/tables/quote.js +4 -0
  59. package/dist/data-plane/server/db/tables/quote.js.map +1 -0
  60. package/dist/data-plane/server/indexing/index.d.ts +2 -0
  61. package/dist/data-plane/server/indexing/index.d.ts.map +1 -1
  62. package/dist/data-plane/server/indexing/index.js +6 -0
  63. package/dist/data-plane/server/indexing/index.js.map +1 -1
  64. package/dist/data-plane/server/indexing/plugins/post-gate.d.ts +10 -0
  65. package/dist/data-plane/server/indexing/plugins/post-gate.d.ts.map +1 -0
  66. package/dist/data-plane/server/indexing/plugins/post-gate.js +101 -0
  67. package/dist/data-plane/server/indexing/plugins/post-gate.js.map +1 -0
  68. package/dist/data-plane/server/indexing/plugins/post.d.ts +2 -0
  69. package/dist/data-plane/server/indexing/plugins/post.d.ts.map +1 -1
  70. package/dist/data-plane/server/indexing/plugins/post.js +122 -15
  71. package/dist/data-plane/server/indexing/plugins/post.js.map +1 -1
  72. package/dist/data-plane/server/indexing/plugins/thread-gate.d.ts.map +1 -1
  73. package/dist/data-plane/server/indexing/plugins/thread-gate.js +12 -0
  74. package/dist/data-plane/server/indexing/plugins/thread-gate.js.map +1 -1
  75. package/dist/data-plane/server/routes/index.d.ts.map +1 -1
  76. package/dist/data-plane/server/routes/index.js +2 -0
  77. package/dist/data-plane/server/routes/index.js.map +1 -1
  78. package/dist/data-plane/server/routes/interactions.d.ts.map +1 -1
  79. package/dist/data-plane/server/routes/interactions.js +2 -1
  80. package/dist/data-plane/server/routes/interactions.js.map +1 -1
  81. package/dist/data-plane/server/routes/quotes.d.ts +6 -0
  82. package/dist/data-plane/server/routes/quotes.d.ts.map +1 -0
  83. package/dist/data-plane/server/routes/quotes.js +27 -0
  84. package/dist/data-plane/server/routes/quotes.js.map +1 -0
  85. package/dist/data-plane/server/routes/records.d.ts.map +1 -1
  86. package/dist/data-plane/server/routes/records.js +11 -1
  87. package/dist/data-plane/server/routes/records.js.map +1 -1
  88. package/dist/data-plane/server/util.d.ts +6 -7
  89. package/dist/data-plane/server/util.d.ts.map +1 -1
  90. package/dist/data-plane/server/util.js +1 -9
  91. package/dist/data-plane/server/util.js.map +1 -1
  92. package/dist/hydration/feed.d.ts +10 -0
  93. package/dist/hydration/feed.d.ts.map +1 -1
  94. package/dist/hydration/feed.js +31 -7
  95. package/dist/hydration/feed.js.map +1 -1
  96. package/dist/hydration/hydrator.d.ts +4 -2
  97. package/dist/hydration/hydrator.d.ts.map +1 -1
  98. package/dist/hydration/hydrator.js +89 -34
  99. package/dist/hydration/hydrator.js.map +1 -1
  100. package/dist/hydration/util.d.ts +0 -1
  101. package/dist/hydration/util.d.ts.map +1 -1
  102. package/dist/hydration/util.js +1 -5
  103. package/dist/hydration/util.js.map +1 -1
  104. package/dist/lexicon/index.d.ts +2 -0
  105. package/dist/lexicon/index.d.ts.map +1 -1
  106. package/dist/lexicon/index.js +4 -0
  107. package/dist/lexicon/index.js.map +1 -1
  108. package/dist/lexicon/lexicons.d.ts +141 -0
  109. package/dist/lexicon/lexicons.d.ts.map +1 -1
  110. package/dist/lexicon/lexicons.js +142 -0
  111. package/dist/lexicon/lexicons.js.map +1 -1
  112. package/dist/lexicon/types/app/bsky/embed/record.d.ts +8 -1
  113. package/dist/lexicon/types/app/bsky/embed/record.d.ts.map +1 -1
  114. package/dist/lexicon/types/app/bsky/embed/record.js +11 -1
  115. package/dist/lexicon/types/app/bsky/embed/record.js.map +1 -1
  116. package/dist/lexicon/types/app/bsky/feed/defs.d.ts +2 -0
  117. package/dist/lexicon/types/app/bsky/feed/defs.d.ts.map +1 -1
  118. package/dist/lexicon/types/app/bsky/feed/defs.js.map +1 -1
  119. package/dist/lexicon/types/app/bsky/feed/getQuotes.d.ts +44 -0
  120. package/dist/lexicon/types/app/bsky/feed/getQuotes.d.ts.map +1 -0
  121. package/dist/lexicon/types/app/bsky/feed/getQuotes.js +3 -0
  122. package/dist/lexicon/types/app/bsky/feed/getQuotes.js.map +1 -0
  123. package/dist/lexicon/types/app/bsky/feed/postgate.d.ts +25 -0
  124. package/dist/lexicon/types/app/bsky/feed/postgate.d.ts.map +1 -0
  125. package/dist/lexicon/types/app/bsky/feed/postgate.js +27 -0
  126. package/dist/lexicon/types/app/bsky/feed/postgate.js.map +1 -0
  127. package/dist/lexicon/types/app/bsky/feed/threadgate.d.ts +2 -0
  128. package/dist/lexicon/types/app/bsky/feed/threadgate.d.ts.map +1 -1
  129. package/dist/lexicon/types/app/bsky/feed/threadgate.js.map +1 -1
  130. package/dist/proto/bsky_connect.d.ts +21 -1
  131. package/dist/proto/bsky_connect.d.ts.map +1 -1
  132. package/dist/proto/bsky_connect.js +20 -0
  133. package/dist/proto/bsky_connect.js.map +1 -1
  134. package/dist/proto/bsky_pb.d.ts +96 -0
  135. package/dist/proto/bsky_pb.d.ts.map +1 -1
  136. package/dist/proto/bsky_pb.js +306 -4
  137. package/dist/proto/bsky_pb.js.map +1 -1
  138. package/dist/util/uris.d.ts +12 -0
  139. package/dist/util/uris.d.ts.map +1 -0
  140. package/dist/util/uris.js +34 -0
  141. package/dist/util/uris.js.map +1 -0
  142. package/dist/views/index.d.ts +8 -2
  143. package/dist/views/index.d.ts.map +1 -1
  144. package/dist/views/index.js +83 -39
  145. package/dist/views/index.js.map +1 -1
  146. package/dist/views/types.d.ts +1 -1
  147. package/dist/views/types.d.ts.map +1 -1
  148. package/dist/views/types.js.map +1 -1
  149. package/dist/views/util.d.ts +11 -1
  150. package/dist/views/util.d.ts.map +1 -1
  151. package/dist/views/util.js +19 -8
  152. package/dist/views/util.js.map +1 -1
  153. package/package.json +4 -4
  154. package/proto/bsky.proto +33 -0
  155. package/src/api/app/bsky/feed/getActorLikes.ts +1 -1
  156. package/src/api/app/bsky/feed/getLikes.ts +1 -1
  157. package/src/api/app/bsky/feed/getPosts.ts +1 -1
  158. package/src/api/app/bsky/feed/getQuotes.ts +105 -0
  159. package/src/api/app/bsky/feed/getRepostedBy.ts +1 -1
  160. package/src/api/app/bsky/feed/searchPosts.ts +1 -1
  161. package/src/api/app/bsky/graph/getFollowers.ts +1 -1
  162. package/src/api/app/bsky/graph/getList.ts +1 -1
  163. package/src/api/app/bsky/notification/listNotifications.ts +32 -6
  164. package/src/api/index.ts +2 -0
  165. package/src/data-plane/server/db/database-schema.ts +7 -3
  166. package/src/data-plane/server/db/migrations/20240723T220700077Z-quotes-post-aggs.ts +12 -0
  167. package/src/data-plane/server/db/migrations/20240723T220703655Z-quotes.ts +28 -0
  168. package/src/data-plane/server/db/migrations/20240801T193939827Z-post-gate.ts +17 -0
  169. package/src/data-plane/server/db/migrations/20240808T224251220Z-post-gate-flags.ts +25 -0
  170. package/src/data-plane/server/db/migrations/index.ts +4 -0
  171. package/src/data-plane/server/db/tables/post-agg.ts +1 -0
  172. package/src/data-plane/server/db/tables/post-gate.ts +12 -0
  173. package/src/data-plane/server/db/tables/post.ts +3 -0
  174. package/src/data-plane/server/db/tables/quote.ts +15 -0
  175. package/src/data-plane/server/indexing/index.ts +7 -0
  176. package/src/data-plane/server/indexing/plugins/post-gate.ts +104 -0
  177. package/src/data-plane/server/indexing/plugins/post.ts +151 -16
  178. package/src/data-plane/server/indexing/plugins/thread-gate.ts +12 -0
  179. package/src/data-plane/server/routes/index.ts +2 -0
  180. package/src/data-plane/server/routes/interactions.ts +2 -1
  181. package/src/data-plane/server/routes/quotes.ts +32 -0
  182. package/src/data-plane/server/routes/records.ts +11 -1
  183. package/src/data-plane/server/util.ts +0 -8
  184. package/src/hydration/feed.ts +58 -12
  185. package/src/hydration/hydrator.ts +94 -22
  186. package/src/hydration/util.ts +0 -4
  187. package/src/lexicon/index.ts +12 -0
  188. package/src/lexicon/lexicons.ts +145 -0
  189. package/src/lexicon/types/app/bsky/embed/record.ts +19 -0
  190. package/src/lexicon/types/app/bsky/feed/defs.ts +2 -0
  191. package/src/lexicon/types/app/bsky/feed/getQuotes.ts +54 -0
  192. package/src/lexicon/types/app/bsky/feed/postgate.ts +47 -0
  193. package/src/lexicon/types/app/bsky/feed/threadgate.ts +2 -0
  194. package/src/proto/bsky_connect.ts +24 -0
  195. package/src/proto/bsky_pb.ts +289 -0
  196. package/src/util/uris.ts +31 -0
  197. package/src/views/index.ts +90 -35
  198. package/src/views/types.ts +1 -0
  199. package/src/views/util.ts +37 -7
  200. package/tests/__snapshots__/feed-generation.test.ts.snap +37 -0
  201. package/tests/data-plane/__snapshots__/indexing.test.ts.snap +18 -0
  202. package/tests/data-plane/indexing.test.ts +1 -0
  203. package/tests/postgates.test.ts +186 -0
  204. package/tests/seed/feed-hidden-replies.ts +62 -0
  205. package/tests/seed/postgates.ts +56 -0
  206. package/tests/views/__snapshots__/author-feed.test.ts.snap +56 -0
  207. package/tests/views/__snapshots__/block-lists.test.ts.snap +6 -0
  208. package/tests/views/__snapshots__/blocks.test.ts.snap +10 -0
  209. package/tests/views/__snapshots__/list-feed.test.ts.snap +22 -0
  210. package/tests/views/__snapshots__/mute-lists.test.ts.snap +8 -0
  211. package/tests/views/__snapshots__/mutes.test.ts.snap +6 -0
  212. package/tests/views/__snapshots__/posts.test.ts.snap +12 -0
  213. package/tests/views/__snapshots__/quotes.test.ts.snap +399 -0
  214. package/tests/views/__snapshots__/thread.test.ts.snap +50 -0
  215. package/tests/views/__snapshots__/timeline.test.ts.snap +170 -0
  216. package/tests/views/author-feed.test.ts +3 -9
  217. package/tests/views/feed-hidden-replies.test.ts +246 -0
  218. package/tests/views/feed-view-post.test.ts +501 -0
  219. package/tests/views/quotes.test.ts +105 -0
@@ -128,12 +128,16 @@ import {
128
128
  GetNotificationSeenResponse,
129
129
  GetNotificationsRequest,
130
130
  GetNotificationsResponse,
131
+ GetPostGateRecordsRequest,
132
+ GetPostGateRecordsResponse,
131
133
  GetPostRecordsRequest,
132
134
  GetPostRecordsResponse,
133
135
  GetPostReplyCountsRequest,
134
136
  GetPostReplyCountsResponse,
135
137
  GetProfileRecordsRequest,
136
138
  GetProfileRecordsResponse,
139
+ GetQuotesBySubjectRequest,
140
+ GetQuotesBySubjectResponse,
137
141
  GetRecordTakedownRequest,
138
142
  GetRecordTakedownResponse,
139
143
  GetRelationshipsRequest,
@@ -309,6 +313,15 @@ export const Service = {
309
313
  O: GetThreadGateRecordsResponse,
310
314
  kind: MethodKind.Unary,
311
315
  },
316
+ /**
317
+ * @generated from rpc bsky.Service.GetPostGateRecords
318
+ */
319
+ getPostGateRecords: {
320
+ name: 'GetPostGateRecords',
321
+ I: GetPostGateRecordsRequest,
322
+ O: GetPostGateRecordsResponse,
323
+ kind: MethodKind.Unary,
324
+ },
312
325
  /**
313
326
  * @generated from rpc bsky.Service.GetLabelerRecords
314
327
  */
@@ -423,6 +436,17 @@ export const Service = {
423
436
  O: GetActorRepostsResponse,
424
437
  kind: MethodKind.Unary,
425
438
  },
439
+ /**
440
+ * Quotes
441
+ *
442
+ * @generated from rpc bsky.Service.GetQuotesBySubject
443
+ */
444
+ getQuotesBySubject: {
445
+ name: 'GetQuotesBySubject',
446
+ I: GetQuotesBySubjectRequest,
447
+ O: GetQuotesBySubjectResponse,
448
+ kind: MethodKind.Unary,
449
+ },
426
450
  /**
427
451
  * Interaction Counts
428
452
  *
@@ -960,6 +960,21 @@ export class PostRecordMeta extends Message<PostRecordMeta> {
960
960
  */
961
961
  isReply = false
962
962
 
963
+ /**
964
+ * @generated from field: bool violates_embedding_rules = 4;
965
+ */
966
+ violatesEmbeddingRules = false
967
+
968
+ /**
969
+ * @generated from field: bool has_post_gate = 5;
970
+ */
971
+ hasPostGate = false
972
+
973
+ /**
974
+ * @generated from field: bool has_thread_gate = 6;
975
+ */
976
+ hasThreadGate = false
977
+
963
978
  constructor(data?: PartialMessage<PostRecordMeta>) {
964
979
  super()
965
980
  proto3.util.initPartial(data, this)
@@ -976,6 +991,24 @@ export class PostRecordMeta extends Message<PostRecordMeta> {
976
991
  },
977
992
  { no: 2, name: 'has_media', kind: 'scalar', T: 8 /* ScalarType.BOOL */ },
978
993
  { no: 3, name: 'is_reply', kind: 'scalar', T: 8 /* ScalarType.BOOL */ },
994
+ {
995
+ no: 4,
996
+ name: 'violates_embedding_rules',
997
+ kind: 'scalar',
998
+ T: 8 /* ScalarType.BOOL */,
999
+ },
1000
+ {
1001
+ no: 5,
1002
+ name: 'has_post_gate',
1003
+ kind: 'scalar',
1004
+ T: 8 /* ScalarType.BOOL */,
1005
+ },
1006
+ {
1007
+ no: 6,
1008
+ name: 'has_thread_gate',
1009
+ kind: 'scalar',
1010
+ T: 8 /* ScalarType.BOOL */,
1011
+ },
979
1012
  ])
980
1013
 
981
1014
  static fromBinary(
@@ -1608,6 +1641,122 @@ export class GetThreadGateRecordsResponse extends Message<GetThreadGateRecordsRe
1608
1641
  }
1609
1642
  }
1610
1643
 
1644
+ /**
1645
+ * @generated from message bsky.GetPostGateRecordsRequest
1646
+ */
1647
+ export class GetPostGateRecordsRequest extends Message<GetPostGateRecordsRequest> {
1648
+ /**
1649
+ * @generated from field: repeated string uris = 1;
1650
+ */
1651
+ uris: string[] = []
1652
+
1653
+ constructor(data?: PartialMessage<GetPostGateRecordsRequest>) {
1654
+ super()
1655
+ proto3.util.initPartial(data, this)
1656
+ }
1657
+
1658
+ static readonly runtime: typeof proto3 = proto3
1659
+ static readonly typeName = 'bsky.GetPostGateRecordsRequest'
1660
+ static readonly fields: FieldList = proto3.util.newFieldList(() => [
1661
+ {
1662
+ no: 1,
1663
+ name: 'uris',
1664
+ kind: 'scalar',
1665
+ T: 9 /* ScalarType.STRING */,
1666
+ repeated: true,
1667
+ },
1668
+ ])
1669
+
1670
+ static fromBinary(
1671
+ bytes: Uint8Array,
1672
+ options?: Partial<BinaryReadOptions>,
1673
+ ): GetPostGateRecordsRequest {
1674
+ return new GetPostGateRecordsRequest().fromBinary(bytes, options)
1675
+ }
1676
+
1677
+ static fromJson(
1678
+ jsonValue: JsonValue,
1679
+ options?: Partial<JsonReadOptions>,
1680
+ ): GetPostGateRecordsRequest {
1681
+ return new GetPostGateRecordsRequest().fromJson(jsonValue, options)
1682
+ }
1683
+
1684
+ static fromJsonString(
1685
+ jsonString: string,
1686
+ options?: Partial<JsonReadOptions>,
1687
+ ): GetPostGateRecordsRequest {
1688
+ return new GetPostGateRecordsRequest().fromJsonString(jsonString, options)
1689
+ }
1690
+
1691
+ static equals(
1692
+ a:
1693
+ | GetPostGateRecordsRequest
1694
+ | PlainMessage<GetPostGateRecordsRequest>
1695
+ | undefined,
1696
+ b:
1697
+ | GetPostGateRecordsRequest
1698
+ | PlainMessage<GetPostGateRecordsRequest>
1699
+ | undefined,
1700
+ ): boolean {
1701
+ return proto3.util.equals(GetPostGateRecordsRequest, a, b)
1702
+ }
1703
+ }
1704
+
1705
+ /**
1706
+ * @generated from message bsky.GetPostGateRecordsResponse
1707
+ */
1708
+ export class GetPostGateRecordsResponse extends Message<GetPostGateRecordsResponse> {
1709
+ /**
1710
+ * @generated from field: repeated bsky.Record records = 1;
1711
+ */
1712
+ records: Record[] = []
1713
+
1714
+ constructor(data?: PartialMessage<GetPostGateRecordsResponse>) {
1715
+ super()
1716
+ proto3.util.initPartial(data, this)
1717
+ }
1718
+
1719
+ static readonly runtime: typeof proto3 = proto3
1720
+ static readonly typeName = 'bsky.GetPostGateRecordsResponse'
1721
+ static readonly fields: FieldList = proto3.util.newFieldList(() => [
1722
+ { no: 1, name: 'records', kind: 'message', T: Record, repeated: true },
1723
+ ])
1724
+
1725
+ static fromBinary(
1726
+ bytes: Uint8Array,
1727
+ options?: Partial<BinaryReadOptions>,
1728
+ ): GetPostGateRecordsResponse {
1729
+ return new GetPostGateRecordsResponse().fromBinary(bytes, options)
1730
+ }
1731
+
1732
+ static fromJson(
1733
+ jsonValue: JsonValue,
1734
+ options?: Partial<JsonReadOptions>,
1735
+ ): GetPostGateRecordsResponse {
1736
+ return new GetPostGateRecordsResponse().fromJson(jsonValue, options)
1737
+ }
1738
+
1739
+ static fromJsonString(
1740
+ jsonString: string,
1741
+ options?: Partial<JsonReadOptions>,
1742
+ ): GetPostGateRecordsResponse {
1743
+ return new GetPostGateRecordsResponse().fromJsonString(jsonString, options)
1744
+ }
1745
+
1746
+ static equals(
1747
+ a:
1748
+ | GetPostGateRecordsResponse
1749
+ | PlainMessage<GetPostGateRecordsResponse>
1750
+ | undefined,
1751
+ b:
1752
+ | GetPostGateRecordsResponse
1753
+ | PlainMessage<GetPostGateRecordsResponse>
1754
+ | undefined,
1755
+ ): boolean {
1756
+ return proto3.util.equals(GetPostGateRecordsResponse, a, b)
1757
+ }
1758
+ }
1759
+
1611
1760
  /**
1612
1761
  * @generated from message bsky.GetLabelerRecordsRequest
1613
1762
  */
@@ -2984,6 +3133,134 @@ export class GetActorLikesResponse extends Message<GetActorLikesResponse> {
2984
3133
  }
2985
3134
  }
2986
3135
 
3136
+ /**
3137
+ * @generated from message bsky.GetQuotesBySubjectRequest
3138
+ */
3139
+ export class GetQuotesBySubjectRequest extends Message<GetQuotesBySubjectRequest> {
3140
+ /**
3141
+ * @generated from field: bsky.RecordRef subject = 1;
3142
+ */
3143
+ subject?: RecordRef
3144
+
3145
+ /**
3146
+ * @generated from field: int32 limit = 2;
3147
+ */
3148
+ limit = 0
3149
+
3150
+ /**
3151
+ * @generated from field: string cursor = 3;
3152
+ */
3153
+ cursor = ''
3154
+
3155
+ constructor(data?: PartialMessage<GetQuotesBySubjectRequest>) {
3156
+ super()
3157
+ proto3.util.initPartial(data, this)
3158
+ }
3159
+
3160
+ static readonly runtime: typeof proto3 = proto3
3161
+ static readonly typeName = 'bsky.GetQuotesBySubjectRequest'
3162
+ static readonly fields: FieldList = proto3.util.newFieldList(() => [
3163
+ { no: 1, name: 'subject', kind: 'message', T: RecordRef },
3164
+ { no: 2, name: 'limit', kind: 'scalar', T: 5 /* ScalarType.INT32 */ },
3165
+ { no: 3, name: 'cursor', kind: 'scalar', T: 9 /* ScalarType.STRING */ },
3166
+ ])
3167
+
3168
+ static fromBinary(
3169
+ bytes: Uint8Array,
3170
+ options?: Partial<BinaryReadOptions>,
3171
+ ): GetQuotesBySubjectRequest {
3172
+ return new GetQuotesBySubjectRequest().fromBinary(bytes, options)
3173
+ }
3174
+
3175
+ static fromJson(
3176
+ jsonValue: JsonValue,
3177
+ options?: Partial<JsonReadOptions>,
3178
+ ): GetQuotesBySubjectRequest {
3179
+ return new GetQuotesBySubjectRequest().fromJson(jsonValue, options)
3180
+ }
3181
+
3182
+ static fromJsonString(
3183
+ jsonString: string,
3184
+ options?: Partial<JsonReadOptions>,
3185
+ ): GetQuotesBySubjectRequest {
3186
+ return new GetQuotesBySubjectRequest().fromJsonString(jsonString, options)
3187
+ }
3188
+
3189
+ static equals(
3190
+ a:
3191
+ | GetQuotesBySubjectRequest
3192
+ | PlainMessage<GetQuotesBySubjectRequest>
3193
+ | undefined,
3194
+ b:
3195
+ | GetQuotesBySubjectRequest
3196
+ | PlainMessage<GetQuotesBySubjectRequest>
3197
+ | undefined,
3198
+ ): boolean {
3199
+ return proto3.util.equals(GetQuotesBySubjectRequest, a, b)
3200
+ }
3201
+ }
3202
+
3203
+ /**
3204
+ * @generated from message bsky.GetQuotesBySubjectResponse
3205
+ */
3206
+ export class GetQuotesBySubjectResponse extends Message<GetQuotesBySubjectResponse> {
3207
+ /**
3208
+ * @generated from field: repeated bsky.RecordRef refs = 1;
3209
+ */
3210
+ refs: RecordRef[] = []
3211
+
3212
+ /**
3213
+ * @generated from field: string cursor = 2;
3214
+ */
3215
+ cursor = ''
3216
+
3217
+ constructor(data?: PartialMessage<GetQuotesBySubjectResponse>) {
3218
+ super()
3219
+ proto3.util.initPartial(data, this)
3220
+ }
3221
+
3222
+ static readonly runtime: typeof proto3 = proto3
3223
+ static readonly typeName = 'bsky.GetQuotesBySubjectResponse'
3224
+ static readonly fields: FieldList = proto3.util.newFieldList(() => [
3225
+ { no: 1, name: 'refs', kind: 'message', T: RecordRef, repeated: true },
3226
+ { no: 2, name: 'cursor', kind: 'scalar', T: 9 /* ScalarType.STRING */ },
3227
+ ])
3228
+
3229
+ static fromBinary(
3230
+ bytes: Uint8Array,
3231
+ options?: Partial<BinaryReadOptions>,
3232
+ ): GetQuotesBySubjectResponse {
3233
+ return new GetQuotesBySubjectResponse().fromBinary(bytes, options)
3234
+ }
3235
+
3236
+ static fromJson(
3237
+ jsonValue: JsonValue,
3238
+ options?: Partial<JsonReadOptions>,
3239
+ ): GetQuotesBySubjectResponse {
3240
+ return new GetQuotesBySubjectResponse().fromJson(jsonValue, options)
3241
+ }
3242
+
3243
+ static fromJsonString(
3244
+ jsonString: string,
3245
+ options?: Partial<JsonReadOptions>,
3246
+ ): GetQuotesBySubjectResponse {
3247
+ return new GetQuotesBySubjectResponse().fromJsonString(jsonString, options)
3248
+ }
3249
+
3250
+ static equals(
3251
+ a:
3252
+ | GetQuotesBySubjectResponse
3253
+ | PlainMessage<GetQuotesBySubjectResponse>
3254
+ | undefined,
3255
+ b:
3256
+ | GetQuotesBySubjectResponse
3257
+ | PlainMessage<GetQuotesBySubjectResponse>
3258
+ | undefined,
3259
+ ): boolean {
3260
+ return proto3.util.equals(GetQuotesBySubjectResponse, a, b)
3261
+ }
3262
+ }
3263
+
2987
3264
  /**
2988
3265
  *
2989
3266
  * Interactions
@@ -3062,6 +3339,11 @@ export class GetInteractionCountsResponse extends Message<GetInteractionCountsRe
3062
3339
  */
3063
3340
  replies: number[] = []
3064
3341
 
3342
+ /**
3343
+ * @generated from field: repeated int32 quotes = 4;
3344
+ */
3345
+ quotes: number[] = []
3346
+
3065
3347
  constructor(data?: PartialMessage<GetInteractionCountsResponse>) {
3066
3348
  super()
3067
3349
  proto3.util.initPartial(data, this)
@@ -3091,6 +3373,13 @@ export class GetInteractionCountsResponse extends Message<GetInteractionCountsRe
3091
3373
  T: 5 /* ScalarType.INT32 */,
3092
3374
  repeated: true,
3093
3375
  },
3376
+ {
3377
+ no: 4,
3378
+ name: 'quotes',
3379
+ kind: 'scalar',
3380
+ T: 5 /* ScalarType.INT32 */,
3381
+ repeated: true,
3382
+ },
3094
3383
  ])
3095
3384
 
3096
3385
  static fromBinary(
@@ -0,0 +1,31 @@
1
+ import assert from 'node:assert'
2
+ import { AtUri } from '@atproto/syntax'
3
+ import { ids } from '../lexicon/lexicons'
4
+
5
+ /**
6
+ * Convert a post URI to a threadgate URI. If the URI is not a valid
7
+ * post URI, return URI unchanged. Threadgate lookups will then fail.
8
+ */
9
+ export function postUriToThreadgateUri(postUri: string) {
10
+ const urip = new AtUri(postUri)
11
+ if (urip.collection === ids.AppBskyFeedPost) {
12
+ urip.collection = ids.AppBskyFeedThreadgate
13
+ }
14
+ return urip.toString()
15
+ }
16
+
17
+ /**
18
+ * Convert a post URI to a postgate URI. If the URI is not a valid
19
+ * post URI, return URI unchanged. Postgate lookups will then fail.
20
+ */
21
+ export function postUriToPostgateUri(postUri: string) {
22
+ const urip = new AtUri(postUri)
23
+ if (urip.collection === ids.AppBskyFeedPost) {
24
+ urip.collection = ids.AppBskyFeedPostgate
25
+ }
26
+ return urip.toString()
27
+ }
28
+
29
+ export function uriToDid(uri: string) {
30
+ return new AtUri(uri).hostname
31
+ }
@@ -28,13 +28,15 @@ import {
28
28
  StarterPackView,
29
29
  StarterPackViewBasic,
30
30
  } from '../lexicon/types/app/bsky/graph/defs'
31
- import { creatorFromUri, parseThreadGate, cidFromBlobJson } from './util'
31
+ import { parseThreadGate, parsePostgate, cidFromBlobJson } from './util'
32
+ import { uriToDid as creatorFromUri } from '../util/uris'
32
33
  import { isListRule } from '../lexicon/types/app/bsky/feed/threadgate'
33
34
  import { isSelfLabels } from '../lexicon/types/com/atproto/label/defs'
34
35
  import {
35
36
  Embed,
36
37
  EmbedBlocked,
37
38
  EmbedNotFound,
39
+ EmbedDetached,
38
40
  EmbedView,
39
41
  ExternalEmbed,
40
42
  ExternalEmbedView,
@@ -61,6 +63,7 @@ import {
61
63
  LabelerViewDetailed,
62
64
  } from '../lexicon/types/app/bsky/labeler/defs'
63
65
  import { Notification } from '../proto/bsky_pb'
66
+ import { postUriToThreadgateUri, postUriToPostgateUri } from '../util/uris'
64
67
 
65
68
  export class Views {
66
69
  constructor(public imgUriBuilder: ImageUriBuilder) {}
@@ -104,6 +107,16 @@ export class Views {
104
107
  return actor.muted || !!actor.mutedByList
105
108
  }
106
109
 
110
+ replyIsHiddenByThreadgate(
111
+ replyUri: string,
112
+ rootPostUri: string,
113
+ state: HydrationState,
114
+ ) {
115
+ const threadgateUri = postUriToThreadgateUri(rootPostUri)
116
+ const threadgate = state.threadgates?.get(threadgateUri)
117
+ return !!threadgate?.record?.hiddenReplies?.includes(replyUri)
118
+ }
119
+
107
120
  profileDetailed(
108
121
  did: string,
109
122
  state: HydrationState,
@@ -291,7 +304,7 @@ export class Views {
291
304
  // ------------
292
305
 
293
306
  list(uri: string, state: HydrationState): ListView | undefined {
294
- const creatorDid = new AtUri(uri).hostname
307
+ const creatorDid = creatorFromUri(uri)
295
308
  const list = state.lists?.get(uri)
296
309
  if (!list) return
297
310
  const creator = this.profile(creatorDid, state)
@@ -316,7 +329,7 @@ export class Views {
316
329
  const listAgg = state.listAggs?.get(uri)
317
330
  const listViewer = state.listViewers?.get(uri)
318
331
  const labels = state.labels?.getBySubject(uri) ?? []
319
- const creator = new AtUri(uri).hostname
332
+ const creator = creatorFromUri(uri)
320
333
  return {
321
334
  uri,
322
335
  cid: list.cid,
@@ -399,7 +412,7 @@ export class Views {
399
412
  const { uri, cid, record } = details
400
413
  if (!uri || !cid || !record) return []
401
414
  if (!isSelfLabels(record.labels)) return []
402
- const src = new AtUri(uri).host // record creator
415
+ const src = creatorFromUri(uri) // record creator
403
416
  const cts =
404
417
  typeof record.createdAt === 'string'
405
418
  ? normalizeDatetimeAlways(record.createdAt)
@@ -529,7 +542,7 @@ export class Views {
529
542
  }
530
543
  }
531
544
 
532
- threadGate(uri: string, state: HydrationState): ThreadgateView | undefined {
545
+ threadgate(uri: string, state: HydrationState): ThreadgateView | undefined {
533
546
  const gate = state.threadgates?.get(uri)
534
547
  if (!gate) return
535
548
  return {
@@ -552,11 +565,7 @@ export class Views {
552
565
  if (!author) return
553
566
  const aggs = state.postAggs?.get(uri)
554
567
  const viewer = state.postViewers?.get(uri)
555
- const gateUri = AtUri.make(
556
- authorDid,
557
- ids.AppBskyFeedThreadgate,
558
- parsedUri.rkey,
559
- ).toString()
568
+ const threadgateUri = postUriToThreadgateUri(uri)
560
569
  const labels = [
561
570
  ...(state.labels?.getBySubject(uri) ?? []),
562
571
  ...this.selfLabels({
@@ -577,6 +586,7 @@ export class Views {
577
586
  replyCount: aggs?.replies ?? 0,
578
587
  repostCount: aggs?.reposts ?? 0,
579
588
  likeCount: aggs?.likes ?? 0,
589
+ quoteCount: aggs?.quotes ?? 0,
580
590
  indexedAt: post.sortedAt.toISOString(),
581
591
  viewer: viewer
582
592
  ? {
@@ -584,11 +594,12 @@ export class Views {
584
594
  like: viewer.like,
585
595
  threadMuted: viewer.threadMuted,
586
596
  replyDisabled: this.userReplyDisabled(uri, state),
597
+ embeddingDisabled: this.userPostEmbeddingDisabled(uri, state),
587
598
  }
588
599
  : undefined,
589
600
  labels,
590
601
  threadgate: !post.record.reply // only hydrate gate on root post
591
- ? this.threadGate(gateUri, state)
602
+ ? this.threadgate(threadgateUri, state)
592
603
  : undefined,
593
604
  }
594
605
  }
@@ -608,12 +619,13 @@ export class Views {
608
619
  }
609
620
  const post = this.post(item.post.uri, state)
610
621
  if (!post) return
622
+ const reply = !postInfo?.violatesThreadGate
623
+ ? this.replyRef(item.post.uri, state)
624
+ : undefined
611
625
  return {
612
626
  post,
613
627
  reason,
614
- reply: !postInfo?.violatesThreadGate
615
- ? this.replyRef(item.post.uri, state)
616
- : undefined,
628
+ reply,
617
629
  }
618
630
  }
619
631
 
@@ -622,15 +634,16 @@ export class Views {
622
634
  if (!postRecord?.reply) return
623
635
  let root = this.maybePost(postRecord.reply.root.uri, state)
624
636
  let parent = this.maybePost(postRecord.reply.parent.uri, state)
625
- if (
626
- !state.ctx?.include3pBlocks &&
627
- state.postBlocks?.get(uri)?.reply &&
628
- isPostView(parent)
629
- ) {
630
- parent = this.blockedPost(parent.uri, parent.author.did, state)
631
- // in a reply to the root of a thread, parent and root are the same post.
632
- if (root.uri === parent.uri) {
633
- root = parent
637
+ if (!state.ctx?.include3pBlocks) {
638
+ const childBlocks = state.postBlocks?.get(uri)
639
+ const parentBlocks = state.postBlocks?.get(parent.uri)
640
+ // if child blocks parent, block parent
641
+ if (isPostView(parent) && childBlocks?.parent) {
642
+ parent = this.blockedPost(parent.uri, parent.author.did, state)
643
+ }
644
+ // if child or parent blocks root, block root
645
+ if (isPostView(root) && (childBlocks?.root || parentBlocks?.root)) {
646
+ root = this.blockedPost(root.uri, root.author.did, state)
634
647
  }
635
648
  }
636
649
  let grandparentAuthor: ProfileViewBasic | undefined
@@ -755,7 +768,10 @@ export class Views {
755
768
  if (height < 1) return undefined
756
769
  const parentUri = state.posts?.get(childUri)?.record.reply?.parent.uri
757
770
  if (!parentUri) return undefined
758
- if (!state.ctx?.include3pBlocks && state.postBlocks?.get(childUri)?.reply) {
771
+ if (
772
+ !state.ctx?.include3pBlocks &&
773
+ state.postBlocks?.get(childUri)?.parent
774
+ ) {
759
775
  return this.blockedPost(parentUri, creatorFromUri(parentUri), state)
760
776
  }
761
777
  const post = this.post(parentUri, state)
@@ -786,7 +802,7 @@ export class Views {
786
802
  if (postInfo?.violatesThreadGate) {
787
803
  return undefined
788
804
  }
789
- if (!state.ctx?.include3pBlocks && state.postBlocks?.get(uri)?.reply) {
805
+ if (!state.ctx?.include3pBlocks && state.postBlocks?.get(uri)?.parent) {
790
806
  return undefined
791
807
  }
792
808
  const post = this.post(uri, state)
@@ -887,6 +903,17 @@ export class Views {
887
903
  }
888
904
  }
889
905
 
906
+ embedDetached(uri: string): { $type: string; record: EmbedDetached } {
907
+ return {
908
+ $type: 'app.bsky.embed.record#view',
909
+ record: {
910
+ $type: 'app.bsky.embed.record#viewDetached',
911
+ uri,
912
+ detached: true,
913
+ },
914
+ }
915
+ }
916
+
890
917
  embedBlocked(
891
918
  uri: string,
892
919
  state: HydrationState,
@@ -944,9 +971,19 @@ export class Views {
944
971
  return this.embedBlocked(uri, state)
945
972
  }
946
973
 
974
+ const post = state.posts?.get(postUri)
975
+ if (post?.violatesEmbeddingRules) {
976
+ return this.embedDetached(uri)
977
+ }
978
+
947
979
  if (parsedUri.collection === ids.AppBskyFeedPost) {
948
980
  const view = this.embedPostView(uri, state, depth)
949
981
  if (!view) return this.embedNotFound(uri)
982
+ const postgateRecordUri = postUriToPostgateUri(parsedUri.toString())
983
+ const postgate = state.postgates?.get(postgateRecordUri)
984
+ if (postgate?.record?.detachedEmbeddingUris?.includes(postUri)) {
985
+ return this.embedDetached(uri)
986
+ }
950
987
  return this.recordEmbedWrapper(view, withTypeTag)
951
988
  } else if (parsedUri.collection === ids.AppBskyFeedGenerator) {
952
989
  const view = this.feedGenerator(uri, state)
@@ -1010,13 +1047,15 @@ export class Views {
1010
1047
  return true
1011
1048
  }
1012
1049
  const rootUriStr: string = post?.record.reply?.root.uri ?? uri
1013
- const gate = state.threadgates?.get(postToGateUri(rootUriStr))?.record
1050
+ const gate = state.threadgates?.get(
1051
+ postUriToThreadgateUri(rootUriStr),
1052
+ )?.record
1014
1053
  const viewer = state.ctx?.viewer
1015
1054
  if (!gate || !viewer) {
1016
1055
  return undefined
1017
1056
  }
1018
1057
  const rootPost = state.posts?.get(rootUriStr)?.record
1019
- const ownerDid = new AtUri(rootUriStr).hostname
1058
+ const ownerDid = creatorFromUri(rootUriStr)
1020
1059
  const {
1021
1060
  canReply,
1022
1061
  allowFollowing,
@@ -1037,6 +1076,30 @@ export class Views {
1037
1076
  return true
1038
1077
  }
1039
1078
 
1079
+ userPostEmbeddingDisabled(
1080
+ uri: string,
1081
+ state: HydrationState,
1082
+ ): boolean | undefined {
1083
+ const post = state.posts?.get(uri)
1084
+ if (!post) {
1085
+ return true
1086
+ }
1087
+ const postgateRecordUri = postUriToPostgateUri(uri)
1088
+ const gate = state.postgates?.get(postgateRecordUri)?.record
1089
+ const viewerDid = state.ctx?.viewer ?? undefined
1090
+ const {
1091
+ embeddingRules: { canEmbed },
1092
+ } = parsePostgate({
1093
+ gate,
1094
+ viewerDid,
1095
+ authorDid: creatorFromUri(uri),
1096
+ })
1097
+ if (canEmbed) {
1098
+ return false
1099
+ }
1100
+ return true
1101
+ }
1102
+
1040
1103
  notification(
1041
1104
  notif: Notification,
1042
1105
  lastSeenAt: string | undefined,
@@ -1093,14 +1156,6 @@ export class Views {
1093
1156
  }
1094
1157
  }
1095
1158
 
1096
- const postToGateUri = (uri: string) => {
1097
- const aturi = new AtUri(uri)
1098
- if (aturi.collection === ids.AppBskyFeedPost) {
1099
- aturi.collection = ids.AppBskyFeedThreadgate
1100
- }
1101
- return aturi.toString()
1102
- }
1103
-
1104
1159
  const getRootUri = (uri: string, post: Post): string => {
1105
1160
  return post.record.reply?.root.uri ?? uri
1106
1161
  }
@@ -39,6 +39,7 @@ export type {
39
39
  View as RecordEmbedView,
40
40
  ViewBlocked as EmbedBlocked,
41
41
  ViewNotFound as EmbedNotFound,
42
+ ViewDetached as EmbedDetached,
42
43
  ViewRecord as PostEmbedView,
43
44
  } from '../lexicon/types/app/bsky/embed/record'
44
45
  export { isMain as isRecordEmbed } from '../lexicon/types/app/bsky/embed/record'