@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
@@ -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'
package/src/views/util.ts CHANGED
@@ -1,4 +1,3 @@
1
- import { AtUri } from '@atproto/syntax'
2
1
  import { BlobRef } from '@atproto/lexicon'
3
2
  import { Record as PostRecord } from '../lexicon/types/app/bsky/feed/post'
4
3
  import {
@@ -7,12 +6,12 @@ import {
7
6
  isListRule,
8
7
  isMentionRule,
9
8
  } from '../lexicon/types/app/bsky/feed/threadgate'
9
+ import {
10
+ Record as PostgateRecord,
11
+ isDisableRule as isPostgateDisableRule,
12
+ } from '../lexicon/types/app/bsky/feed/postgate'
10
13
  import { isMention } from '../lexicon/types/app/bsky/richtext/facet'
11
14
 
12
- export const creatorFromUri = (uri: string): string => {
13
- return new AtUri(uri).hostname
14
- }
15
-
16
15
  export const parseThreadGate = (
17
16
  replierDid: string,
18
17
  ownerDid: string,
@@ -27,8 +26,8 @@ export const parseThreadGate = (
27
26
  return { canReply: true }
28
27
  }
29
28
 
30
- const allowMentions = !!gate.allow.find(isMentionRule)
31
- const allowFollowing = !!gate.allow.find(isFollowingRule)
29
+ const allowMentions = gate.allow.some(isMentionRule)
30
+ const allowFollowing = gate.allow.some(isFollowingRule)
32
31
  const allowListUris = gate.allow?.filter(isListRule).map((item) => item.list)
33
32
 
34
33
  // check mentions first since it's quick and synchronous
@@ -62,3 +61,34 @@ export const cidFromBlobJson = (json: BlobRef) => {
62
61
  }
63
62
  return (json['cid'] ?? '') as string
64
63
  }
64
+
65
+ export const parsePostgate = ({
66
+ gate,
67
+ viewerDid,
68
+ authorDid,
69
+ }: {
70
+ gate: PostgateRecord | undefined
71
+ viewerDid: string | undefined
72
+ authorDid: string
73
+ }): ParsedPostgate => {
74
+ if (viewerDid === authorDid) {
75
+ return { embeddingRules: { canEmbed: true } }
76
+ }
77
+ // default state is unset, allow everyone
78
+ if (!gate || !gate.embeddingRules) {
79
+ return { embeddingRules: { canEmbed: true } }
80
+ }
81
+
82
+ const disabled = gate.embeddingRules.some(isPostgateDisableRule)
83
+ if (disabled) {
84
+ return { embeddingRules: { canEmbed: false } }
85
+ }
86
+
87
+ return { embeddingRules: { canEmbed: true } }
88
+ }
89
+
90
+ type ParsedPostgate = {
91
+ embeddingRules: {
92
+ canEmbed: boolean
93
+ }
94
+ }
@@ -26,6 +26,7 @@ Object {
26
26
  "indexedAt": "1970-01-01T00:00:00.000Z",
27
27
  "labels": Array [],
28
28
  "likeCount": 0,
29
+ "quoteCount": 0,
29
30
  "record": Object {
30
31
  "$type": "app.bsky.feed.post",
31
32
  "createdAt": "1970-01-01T00:00:00.000Z",
@@ -42,6 +43,7 @@ Object {
42
43
  "repostCount": 0,
43
44
  "uri": "record(0)",
44
45
  "viewer": Object {
46
+ "embeddingDisabled": false,
45
47
  "threadMuted": false,
46
48
  },
47
49
  }
@@ -73,6 +75,7 @@ Object {
73
75
  "indexedAt": "1970-01-01T00:00:00.000Z",
74
76
  "labels": Array [],
75
77
  "likeCount": 0,
78
+ "quoteCount": 0,
76
79
  "record": Object {
77
80
  "$type": "app.bsky.feed.post",
78
81
  "createdAt": "1970-01-01T00:00:00.000Z",
@@ -89,6 +92,7 @@ Object {
89
92
  "repostCount": 0,
90
93
  "uri": "record(0)",
91
94
  "viewer": Object {
95
+ "embeddingDisabled": false,
92
96
  "threadMuted": false,
93
97
  },
94
98
  }
@@ -160,6 +164,7 @@ Object {
160
164
  "indexedAt": "1970-01-01T00:00:00.000Z",
161
165
  "labels": Array [],
162
166
  "likeCount": 0,
167
+ "quoteCount": 0,
163
168
  "record": Object {
164
169
  "$type": "app.bsky.feed.post",
165
170
  "createdAt": "1970-01-01T00:00:00.000Z",
@@ -176,6 +181,7 @@ Object {
176
181
  "repostCount": 0,
177
182
  "uri": "record(0)",
178
183
  "viewer": Object {
184
+ "embeddingDisabled": false,
179
185
  "threadMuted": false,
180
186
  },
181
187
  }
@@ -249,6 +255,7 @@ Object {
249
255
  "indexedAt": "1970-01-01T00:00:00.000Z",
250
256
  "labels": Array [],
251
257
  "likeCount": 0,
258
+ "quoteCount": 0,
252
259
  "record": Object {
253
260
  "$type": "app.bsky.feed.post",
254
261
  "createdAt": "1970-01-01T00:00:00.000Z",
@@ -265,6 +272,7 @@ Object {
265
272
  "repostCount": 0,
266
273
  "uri": "record(0)",
267
274
  "viewer": Object {
275
+ "embeddingDisabled": false,
268
276
  "threadMuted": false,
269
277
  },
270
278
  }
@@ -531,6 +539,7 @@ Array [
531
539
  },
532
540
  ],
533
541
  "likeCount": 0,
542
+ "quoteCount": 0,
534
543
  "record": Object {
535
544
  "$type": "app.bsky.feed.post",
536
545
  "createdAt": "1970-01-01T00:00:00.000Z",
@@ -548,6 +557,7 @@ Array [
548
557
  "repostCount": 0,
549
558
  "uri": "record(0)",
550
559
  "viewer": Object {
560
+ "embeddingDisabled": false,
551
561
  "threadMuted": false,
552
562
  },
553
563
  },
@@ -573,6 +583,7 @@ Array [
573
583
  "indexedAt": "1970-01-01T00:00:00.000Z",
574
584
  "labels": Array [],
575
585
  "likeCount": 0,
586
+ "quoteCount": 1,
576
587
  "record": Object {
577
588
  "$type": "app.bsky.feed.post",
578
589
  "createdAt": "1970-01-01T00:00:00.000Z",
@@ -586,6 +597,7 @@ Array [
586
597
  "repostCount": 0,
587
598
  "uri": "record(2)",
588
599
  "viewer": Object {
600
+ "embeddingDisabled": false,
589
601
  "threadMuted": false,
590
602
  },
591
603
  },
@@ -662,6 +674,7 @@ Array [
662
674
  "indexedAt": "1970-01-01T00:00:00.000Z",
663
675
  "labels": Array [],
664
676
  "likeCount": 2,
677
+ "quoteCount": 1,
665
678
  "record": Object {
666
679
  "$type": "app.bsky.feed.post",
667
680
  "createdAt": "1970-01-01T00:00:00.000Z",
@@ -707,6 +720,7 @@ Array [
707
720
  "repostCount": 0,
708
721
  "uri": "record(5)",
709
722
  "viewer": Object {
723
+ "embeddingDisabled": false,
710
724
  "like": "record(8)",
711
725
  "threadMuted": false,
712
726
  },
@@ -730,6 +744,7 @@ Array [
730
744
  "indexedAt": "1970-01-01T00:00:00.000Z",
731
745
  "labels": Array [],
732
746
  "likeCount": 0,
747
+ "quoteCount": 0,
733
748
  "record": Object {
734
749
  "$type": "app.bsky.feed.post",
735
750
  "createdAt": "1970-01-01T00:00:00.000Z",
@@ -749,6 +764,7 @@ Array [
749
764
  "repostCount": 0,
750
765
  "uri": "record(9)",
751
766
  "viewer": Object {
767
+ "embeddingDisabled": false,
752
768
  "threadMuted": false,
753
769
  },
754
770
  },
@@ -786,6 +802,7 @@ Array [
786
802
  "indexedAt": "1970-01-01T00:00:00.000Z",
787
803
  "labels": Array [],
788
804
  "likeCount": 3,
805
+ "quoteCount": 0,
789
806
  "record": Object {
790
807
  "$type": "app.bsky.feed.post",
791
808
  "createdAt": "1970-01-01T00:00:00.000000Z",
@@ -795,6 +812,7 @@ Array [
795
812
  "repostCount": 1,
796
813
  "uri": "record(10)",
797
814
  "viewer": Object {
815
+ "embeddingDisabled": false,
798
816
  "threadMuted": false,
799
817
  },
800
818
  },
@@ -831,6 +849,7 @@ Array [
831
849
  "indexedAt": "1970-01-01T00:00:00.000Z",
832
850
  "labels": Array [],
833
851
  "likeCount": 3,
852
+ "quoteCount": 0,
834
853
  "record": Object {
835
854
  "$type": "app.bsky.feed.post",
836
855
  "createdAt": "1970-01-01T00:00:00.000000Z",
@@ -840,6 +859,7 @@ Array [
840
859
  "repostCount": 1,
841
860
  "uri": "record(10)",
842
861
  "viewer": Object {
862
+ "embeddingDisabled": false,
843
863
  "threadMuted": false,
844
864
  },
845
865
  },
@@ -987,6 +1007,7 @@ Array [
987
1007
  "indexedAt": "1970-01-01T00:00:00.000Z",
988
1008
  "labels": Array [],
989
1009
  "likeCount": 0,
1010
+ "quoteCount": 1,
990
1011
  "record": Object {
991
1012
  "$type": "app.bsky.feed.post",
992
1013
  "createdAt": "1970-01-01T00:00:00.000Z",
@@ -1017,6 +1038,7 @@ Array [
1017
1038
  "repostCount": 1,
1018
1039
  "uri": "record(11)",
1019
1040
  "viewer": Object {
1041
+ "embeddingDisabled": false,
1020
1042
  "threadMuted": false,
1021
1043
  },
1022
1044
  },
@@ -1079,6 +1101,7 @@ Array [
1079
1101
  },
1080
1102
  ],
1081
1103
  "likeCount": 0,
1104
+ "quoteCount": 0,
1082
1105
  "record": Object {
1083
1106
  "$type": "app.bsky.feed.post",
1084
1107
  "createdAt": "1970-01-01T00:00:00.000Z",
@@ -1157,6 +1180,7 @@ Array [
1157
1180
  "indexedAt": "1970-01-01T00:00:00.000Z",
1158
1181
  "labels": Array [],
1159
1182
  "likeCount": 2,
1183
+ "quoteCount": 1,
1160
1184
  "record": Object {
1161
1185
  "$type": "app.bsky.feed.post",
1162
1186
  "createdAt": "1970-01-01T00:00:00.000Z",
@@ -1215,6 +1239,7 @@ Array [
1215
1239
  "indexedAt": "1970-01-01T00:00:00.000Z",
1216
1240
  "labels": Array [],
1217
1241
  "likeCount": 0,
1242
+ "quoteCount": 0,
1218
1243
  "record": Object {
1219
1244
  "$type": "app.bsky.feed.post",
1220
1245
  "createdAt": "1970-01-01T00:00:00.000Z",
@@ -1264,6 +1289,7 @@ Array [
1264
1289
  "indexedAt": "1970-01-01T00:00:00.000Z",
1265
1290
  "labels": Array [],
1266
1291
  "likeCount": 3,
1292
+ "quoteCount": 0,
1267
1293
  "record": Object {
1268
1294
  "$type": "app.bsky.feed.post",
1269
1295
  "createdAt": "1970-01-01T00:00:00.000000Z",
@@ -1302,6 +1328,7 @@ Array [
1302
1328
  "indexedAt": "1970-01-01T00:00:00.000Z",
1303
1329
  "labels": Array [],
1304
1330
  "likeCount": 3,
1331
+ "quoteCount": 0,
1305
1332
  "record": Object {
1306
1333
  "$type": "app.bsky.feed.post",
1307
1334
  "createdAt": "1970-01-01T00:00:00.000000Z",
@@ -1360,6 +1387,7 @@ Array [
1360
1387
  },
1361
1388
  ],
1362
1389
  "likeCount": 0,
1390
+ "quoteCount": 0,
1363
1391
  "record": Object {
1364
1392
  "$type": "app.bsky.feed.post",
1365
1393
  "createdAt": "1970-01-01T00:00:00.000Z",
@@ -1377,6 +1405,7 @@ Array [
1377
1405
  "repostCount": 0,
1378
1406
  "uri": "record(0)",
1379
1407
  "viewer": Object {
1408
+ "embeddingDisabled": false,
1380
1409
  "threadMuted": false,
1381
1410
  },
1382
1411
  },
@@ -1453,6 +1482,7 @@ Array [
1453
1482
  "indexedAt": "1970-01-01T00:00:00.000Z",
1454
1483
  "labels": Array [],
1455
1484
  "likeCount": 2,
1485
+ "quoteCount": 1,
1456
1486
  "record": Object {
1457
1487
  "$type": "app.bsky.feed.post",
1458
1488
  "createdAt": "1970-01-01T00:00:00.000Z",
@@ -1498,6 +1528,7 @@ Array [
1498
1528
  "repostCount": 0,
1499
1529
  "uri": "record(2)",
1500
1530
  "viewer": Object {
1531
+ "embeddingDisabled": false,
1501
1532
  "like": "record(8)",
1502
1533
  "threadMuted": false,
1503
1534
  },
@@ -1521,6 +1552,7 @@ Array [
1521
1552
  "indexedAt": "1970-01-01T00:00:00.000Z",
1522
1553
  "labels": Array [],
1523
1554
  "likeCount": 0,
1555
+ "quoteCount": 0,
1524
1556
  "record": Object {
1525
1557
  "$type": "app.bsky.feed.post",
1526
1558
  "createdAt": "1970-01-01T00:00:00.000Z",
@@ -1540,6 +1572,7 @@ Array [
1540
1572
  "repostCount": 0,
1541
1573
  "uri": "record(9)",
1542
1574
  "viewer": Object {
1575
+ "embeddingDisabled": false,
1543
1576
  "threadMuted": false,
1544
1577
  },
1545
1578
  },
@@ -1577,6 +1610,7 @@ Array [
1577
1610
  "indexedAt": "1970-01-01T00:00:00.000Z",
1578
1611
  "labels": Array [],
1579
1612
  "likeCount": 3,
1613
+ "quoteCount": 0,
1580
1614
  "record": Object {
1581
1615
  "$type": "app.bsky.feed.post",
1582
1616
  "createdAt": "1970-01-01T00:00:00.000000Z",
@@ -1586,6 +1620,7 @@ Array [
1586
1620
  "repostCount": 1,
1587
1621
  "uri": "record(10)",
1588
1622
  "viewer": Object {
1623
+ "embeddingDisabled": false,
1589
1624
  "threadMuted": false,
1590
1625
  },
1591
1626
  },
@@ -1622,6 +1657,7 @@ Array [
1622
1657
  "indexedAt": "1970-01-01T00:00:00.000Z",
1623
1658
  "labels": Array [],
1624
1659
  "likeCount": 3,
1660
+ "quoteCount": 0,
1625
1661
  "record": Object {
1626
1662
  "$type": "app.bsky.feed.post",
1627
1663
  "createdAt": "1970-01-01T00:00:00.000000Z",
@@ -1631,6 +1667,7 @@ Array [
1631
1667
  "repostCount": 1,
1632
1668
  "uri": "record(10)",
1633
1669
  "viewer": Object {
1670
+ "embeddingDisabled": false,
1634
1671
  "threadMuted": false,
1635
1672
  },
1636
1673
  },