@atproto/bsky 0.0.76 → 0.0.78

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 (226) hide show
  1. package/CHANGELOG.md +20 -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/getListFeed.d.ts.map +1 -1
  7. package/dist/api/app/bsky/feed/getListFeed.js +19 -3
  8. package/dist/api/app/bsky/feed/getListFeed.js.map +1 -1
  9. package/dist/api/app/bsky/feed/getPosts.js +4 -4
  10. package/dist/api/app/bsky/feed/getPosts.js.map +1 -1
  11. package/dist/api/app/bsky/feed/getQuotes.d.ts +4 -0
  12. package/dist/api/app/bsky/feed/getQuotes.d.ts.map +1 -0
  13. package/dist/api/app/bsky/feed/getQuotes.js +67 -0
  14. package/dist/api/app/bsky/feed/getQuotes.js.map +1 -0
  15. package/dist/api/app/bsky/feed/getRepostedBy.js +6 -6
  16. package/dist/api/app/bsky/feed/getRepostedBy.js.map +1 -1
  17. package/dist/api/app/bsky/feed/searchPosts.js +4 -4
  18. package/dist/api/app/bsky/feed/searchPosts.js.map +1 -1
  19. package/dist/api/app/bsky/graph/getFollowers.js +8 -8
  20. package/dist/api/app/bsky/graph/getFollowers.js.map +1 -1
  21. package/dist/api/app/bsky/graph/getList.js +7 -7
  22. package/dist/api/app/bsky/graph/getList.js.map +1 -1
  23. package/dist/api/app/bsky/notification/listNotifications.d.ts.map +1 -1
  24. package/dist/api/app/bsky/notification/listNotifications.js +29 -8
  25. package/dist/api/app/bsky/notification/listNotifications.js.map +1 -1
  26. package/dist/api/index.d.ts.map +1 -1
  27. package/dist/api/index.js +2 -0
  28. package/dist/api/index.js.map +1 -1
  29. package/dist/data-plane/server/db/database-schema.d.ts +4 -2
  30. package/dist/data-plane/server/db/database-schema.d.ts.map +1 -1
  31. package/dist/data-plane/server/db/migrations/20240723T220700077Z-quotes-post-aggs.d.ts +4 -0
  32. package/dist/data-plane/server/db/migrations/20240723T220700077Z-quotes-post-aggs.d.ts.map +1 -0
  33. package/dist/data-plane/server/db/migrations/20240723T220700077Z-quotes-post-aggs.js +15 -0
  34. package/dist/data-plane/server/db/migrations/20240723T220700077Z-quotes-post-aggs.js.map +1 -0
  35. package/dist/data-plane/server/db/migrations/20240723T220703655Z-quotes.d.ts +4 -0
  36. package/dist/data-plane/server/db/migrations/20240723T220703655Z-quotes.d.ts.map +1 -0
  37. package/dist/data-plane/server/db/migrations/20240723T220703655Z-quotes.js +30 -0
  38. package/dist/data-plane/server/db/migrations/20240723T220703655Z-quotes.js.map +1 -0
  39. package/dist/data-plane/server/db/migrations/20240801T193939827Z-post-gate.d.ts +4 -0
  40. package/dist/data-plane/server/db/migrations/20240801T193939827Z-post-gate.d.ts.map +1 -0
  41. package/dist/data-plane/server/db/migrations/20240801T193939827Z-post-gate.js +20 -0
  42. package/dist/data-plane/server/db/migrations/20240801T193939827Z-post-gate.js.map +1 -0
  43. package/dist/data-plane/server/db/migrations/20240808T224251220Z-post-gate-flags.d.ts +4 -0
  44. package/dist/data-plane/server/db/migrations/20240808T224251220Z-post-gate-flags.d.ts.map +1 -0
  45. package/dist/data-plane/server/db/migrations/20240808T224251220Z-post-gate-flags.js +28 -0
  46. package/dist/data-plane/server/db/migrations/20240808T224251220Z-post-gate-flags.js.map +1 -0
  47. package/dist/data-plane/server/db/migrations/index.d.ts +4 -0
  48. package/dist/data-plane/server/db/migrations/index.d.ts.map +1 -1
  49. package/dist/data-plane/server/db/migrations/index.js +5 -1
  50. package/dist/data-plane/server/db/migrations/index.js.map +1 -1
  51. package/dist/data-plane/server/db/tables/post-agg.d.ts +1 -0
  52. package/dist/data-plane/server/db/tables/post-agg.d.ts.map +1 -1
  53. package/dist/data-plane/server/db/tables/post-gate.d.ts +14 -0
  54. package/dist/data-plane/server/db/tables/post-gate.d.ts.map +1 -0
  55. package/dist/data-plane/server/db/tables/post-gate.js +4 -0
  56. package/dist/data-plane/server/db/tables/post-gate.js.map +1 -0
  57. package/dist/data-plane/server/db/tables/post.d.ts +3 -0
  58. package/dist/data-plane/server/db/tables/post.d.ts.map +1 -1
  59. package/dist/data-plane/server/db/tables/quote.d.ts +16 -0
  60. package/dist/data-plane/server/db/tables/quote.d.ts.map +1 -0
  61. package/dist/data-plane/server/db/tables/quote.js +4 -0
  62. package/dist/data-plane/server/db/tables/quote.js.map +1 -0
  63. package/dist/data-plane/server/indexing/index.d.ts +2 -0
  64. package/dist/data-plane/server/indexing/index.d.ts.map +1 -1
  65. package/dist/data-plane/server/indexing/index.js +6 -0
  66. package/dist/data-plane/server/indexing/index.js.map +1 -1
  67. package/dist/data-plane/server/indexing/plugins/post-gate.d.ts +10 -0
  68. package/dist/data-plane/server/indexing/plugins/post-gate.d.ts.map +1 -0
  69. package/dist/data-plane/server/indexing/plugins/post-gate.js +101 -0
  70. package/dist/data-plane/server/indexing/plugins/post-gate.js.map +1 -0
  71. package/dist/data-plane/server/indexing/plugins/post.d.ts +2 -0
  72. package/dist/data-plane/server/indexing/plugins/post.d.ts.map +1 -1
  73. package/dist/data-plane/server/indexing/plugins/post.js +122 -15
  74. package/dist/data-plane/server/indexing/plugins/post.js.map +1 -1
  75. package/dist/data-plane/server/indexing/plugins/thread-gate.d.ts.map +1 -1
  76. package/dist/data-plane/server/indexing/plugins/thread-gate.js +12 -0
  77. package/dist/data-plane/server/indexing/plugins/thread-gate.js.map +1 -1
  78. package/dist/data-plane/server/routes/index.d.ts.map +1 -1
  79. package/dist/data-plane/server/routes/index.js +2 -0
  80. package/dist/data-plane/server/routes/index.js.map +1 -1
  81. package/dist/data-plane/server/routes/interactions.d.ts.map +1 -1
  82. package/dist/data-plane/server/routes/interactions.js +2 -1
  83. package/dist/data-plane/server/routes/interactions.js.map +1 -1
  84. package/dist/data-plane/server/routes/quotes.d.ts +6 -0
  85. package/dist/data-plane/server/routes/quotes.d.ts.map +1 -0
  86. package/dist/data-plane/server/routes/quotes.js +27 -0
  87. package/dist/data-plane/server/routes/quotes.js.map +1 -0
  88. package/dist/data-plane/server/routes/records.d.ts.map +1 -1
  89. package/dist/data-plane/server/routes/records.js +11 -1
  90. package/dist/data-plane/server/routes/records.js.map +1 -1
  91. package/dist/data-plane/server/util.d.ts +6 -7
  92. package/dist/data-plane/server/util.d.ts.map +1 -1
  93. package/dist/data-plane/server/util.js +1 -9
  94. package/dist/data-plane/server/util.js.map +1 -1
  95. package/dist/hydration/feed.d.ts +10 -0
  96. package/dist/hydration/feed.d.ts.map +1 -1
  97. package/dist/hydration/feed.js +31 -7
  98. package/dist/hydration/feed.js.map +1 -1
  99. package/dist/hydration/hydrator.d.ts +4 -2
  100. package/dist/hydration/hydrator.d.ts.map +1 -1
  101. package/dist/hydration/hydrator.js +89 -34
  102. package/dist/hydration/hydrator.js.map +1 -1
  103. package/dist/hydration/util.d.ts +0 -1
  104. package/dist/hydration/util.d.ts.map +1 -1
  105. package/dist/hydration/util.js +1 -5
  106. package/dist/hydration/util.js.map +1 -1
  107. package/dist/lexicon/index.d.ts +2 -0
  108. package/dist/lexicon/index.d.ts.map +1 -1
  109. package/dist/lexicon/index.js +4 -0
  110. package/dist/lexicon/index.js.map +1 -1
  111. package/dist/lexicon/lexicons.d.ts +144 -0
  112. package/dist/lexicon/lexicons.d.ts.map +1 -1
  113. package/dist/lexicon/lexicons.js +146 -1
  114. package/dist/lexicon/lexicons.js.map +1 -1
  115. package/dist/lexicon/types/app/bsky/embed/record.d.ts +9 -1
  116. package/dist/lexicon/types/app/bsky/embed/record.d.ts.map +1 -1
  117. package/dist/lexicon/types/app/bsky/embed/record.js +11 -1
  118. package/dist/lexicon/types/app/bsky/embed/record.js.map +1 -1
  119. package/dist/lexicon/types/app/bsky/feed/defs.d.ts +2 -0
  120. package/dist/lexicon/types/app/bsky/feed/defs.d.ts.map +1 -1
  121. package/dist/lexicon/types/app/bsky/feed/defs.js.map +1 -1
  122. package/dist/lexicon/types/app/bsky/feed/getQuotes.d.ts +44 -0
  123. package/dist/lexicon/types/app/bsky/feed/getQuotes.d.ts.map +1 -0
  124. package/dist/lexicon/types/app/bsky/feed/getQuotes.js +3 -0
  125. package/dist/lexicon/types/app/bsky/feed/getQuotes.js.map +1 -0
  126. package/dist/lexicon/types/app/bsky/feed/postgate.d.ts +25 -0
  127. package/dist/lexicon/types/app/bsky/feed/postgate.d.ts.map +1 -0
  128. package/dist/lexicon/types/app/bsky/feed/postgate.js +27 -0
  129. package/dist/lexicon/types/app/bsky/feed/postgate.js.map +1 -0
  130. package/dist/lexicon/types/app/bsky/feed/threadgate.d.ts +2 -0
  131. package/dist/lexicon/types/app/bsky/feed/threadgate.d.ts.map +1 -1
  132. package/dist/lexicon/types/app/bsky/feed/threadgate.js.map +1 -1
  133. package/dist/proto/bsky_connect.d.ts +30 -1
  134. package/dist/proto/bsky_connect.d.ts.map +1 -1
  135. package/dist/proto/bsky_connect.js +29 -0
  136. package/dist/proto/bsky_connect.js.map +1 -1
  137. package/dist/proto/bsky_pb.d.ts +135 -1
  138. package/dist/proto/bsky_pb.d.ts.map +1 -1
  139. package/dist/proto/bsky_pb.js +425 -5
  140. package/dist/proto/bsky_pb.js.map +1 -1
  141. package/dist/util/uris.d.ts +12 -0
  142. package/dist/util/uris.d.ts.map +1 -0
  143. package/dist/util/uris.js +34 -0
  144. package/dist/util/uris.js.map +1 -0
  145. package/dist/views/index.d.ts +8 -2
  146. package/dist/views/index.d.ts.map +1 -1
  147. package/dist/views/index.js +84 -39
  148. package/dist/views/index.js.map +1 -1
  149. package/dist/views/types.d.ts +1 -1
  150. package/dist/views/types.d.ts.map +1 -1
  151. package/dist/views/types.js.map +1 -1
  152. package/dist/views/util.d.ts +11 -1
  153. package/dist/views/util.d.ts.map +1 -1
  154. package/dist/views/util.js +19 -8
  155. package/dist/views/util.js.map +1 -1
  156. package/package.json +4 -4
  157. package/proto/bsky.proto +42 -2
  158. package/src/api/app/bsky/feed/getActorLikes.ts +1 -1
  159. package/src/api/app/bsky/feed/getLikes.ts +1 -1
  160. package/src/api/app/bsky/feed/getListFeed.ts +30 -3
  161. package/src/api/app/bsky/feed/getPosts.ts +1 -1
  162. package/src/api/app/bsky/feed/getQuotes.ts +108 -0
  163. package/src/api/app/bsky/feed/getRepostedBy.ts +1 -1
  164. package/src/api/app/bsky/feed/searchPosts.ts +1 -1
  165. package/src/api/app/bsky/graph/getFollowers.ts +1 -1
  166. package/src/api/app/bsky/graph/getList.ts +5 -5
  167. package/src/api/app/bsky/notification/listNotifications.ts +32 -6
  168. package/src/api/index.ts +2 -0
  169. package/src/data-plane/server/db/database-schema.ts +7 -3
  170. package/src/data-plane/server/db/migrations/20240723T220700077Z-quotes-post-aggs.ts +12 -0
  171. package/src/data-plane/server/db/migrations/20240723T220703655Z-quotes.ts +28 -0
  172. package/src/data-plane/server/db/migrations/20240801T193939827Z-post-gate.ts +17 -0
  173. package/src/data-plane/server/db/migrations/20240808T224251220Z-post-gate-flags.ts +25 -0
  174. package/src/data-plane/server/db/migrations/index.ts +4 -0
  175. package/src/data-plane/server/db/tables/post-agg.ts +1 -0
  176. package/src/data-plane/server/db/tables/post-gate.ts +12 -0
  177. package/src/data-plane/server/db/tables/post.ts +3 -0
  178. package/src/data-plane/server/db/tables/quote.ts +15 -0
  179. package/src/data-plane/server/indexing/index.ts +7 -0
  180. package/src/data-plane/server/indexing/plugins/post-gate.ts +104 -0
  181. package/src/data-plane/server/indexing/plugins/post.ts +151 -16
  182. package/src/data-plane/server/indexing/plugins/thread-gate.ts +12 -0
  183. package/src/data-plane/server/routes/index.ts +2 -0
  184. package/src/data-plane/server/routes/interactions.ts +2 -1
  185. package/src/data-plane/server/routes/quotes.ts +32 -0
  186. package/src/data-plane/server/routes/records.ts +11 -1
  187. package/src/data-plane/server/util.ts +0 -8
  188. package/src/hydration/feed.ts +58 -12
  189. package/src/hydration/hydrator.ts +94 -22
  190. package/src/hydration/util.ts +0 -4
  191. package/src/lexicon/index.ts +12 -0
  192. package/src/lexicon/lexicons.ts +149 -1
  193. package/src/lexicon/types/app/bsky/embed/record.ts +20 -0
  194. package/src/lexicon/types/app/bsky/feed/defs.ts +2 -0
  195. package/src/lexicon/types/app/bsky/feed/getQuotes.ts +54 -0
  196. package/src/lexicon/types/app/bsky/feed/postgate.ts +47 -0
  197. package/src/lexicon/types/app/bsky/feed/threadgate.ts +2 -0
  198. package/src/proto/bsky_connect.ts +35 -0
  199. package/src/proto/bsky_pb.ts +424 -1
  200. package/src/util/uris.ts +31 -0
  201. package/src/views/index.ts +91 -35
  202. package/src/views/types.ts +1 -0
  203. package/src/views/util.ts +37 -7
  204. package/tests/__snapshots__/feed-generation.test.ts.snap +42 -0
  205. package/tests/data-plane/__snapshots__/indexing.test.ts.snap +20 -0
  206. package/tests/data-plane/indexing.test.ts +1 -0
  207. package/tests/postgates.test.ts +186 -0
  208. package/tests/seed/feed-hidden-replies.ts +62 -0
  209. package/tests/seed/postgates.ts +56 -0
  210. package/tests/views/__snapshots__/author-feed.test.ts.snap +65 -0
  211. package/tests/views/__snapshots__/block-lists.test.ts.snap +7 -0
  212. package/tests/views/__snapshots__/blocks.test.ts.snap +11 -0
  213. package/tests/views/__snapshots__/list-feed.test.ts.snap +24 -0
  214. package/tests/views/__snapshots__/lists.test.ts.snap +185 -1
  215. package/tests/views/__snapshots__/mute-lists.test.ts.snap +8 -0
  216. package/tests/views/__snapshots__/mutes.test.ts.snap +6 -0
  217. package/tests/views/__snapshots__/posts.test.ts.snap +15 -0
  218. package/tests/views/__snapshots__/quotes.test.ts.snap +402 -0
  219. package/tests/views/__snapshots__/thread.test.ts.snap +50 -0
  220. package/tests/views/__snapshots__/timeline.test.ts.snap +191 -0
  221. package/tests/views/author-feed.test.ts +3 -9
  222. package/tests/views/feed-hidden-replies.test.ts +246 -0
  223. package/tests/views/feed-view-post.test.ts +501 -0
  224. package/tests/views/list-feed.test.ts +12 -0
  225. package/tests/views/lists.test.ts +83 -18
  226. package/tests/views/quotes.test.ts +105 -0
@@ -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.76",
3
+ "version": "0.0.78",
4
4
  "license": "MIT",
5
5
  "description": "Reference implementation of app.bsky App View (Bluesky API)",
6
6
  "keywords": [
@@ -40,7 +40,7 @@
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",
43
+ "@atproto/api": "^0.13.3",
44
44
  "@atproto/common": "^0.4.1",
45
45
  "@atproto/crypto": "^0.4.0",
46
46
  "@atproto/identity": "^0.4.0",
@@ -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.3",
66
66
  "@atproto/lex-cli": "^0.5.0",
67
- "@atproto/pds": "^0.4.50",
67
+ "@atproto/pds": "^0.4.53",
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
  }
@@ -220,6 +231,17 @@ message GetLikesBySubjectSortedResponse {
220
231
  string cursor = 2;
221
232
  }
222
233
 
234
+ message GetQuotesBySubjectSortedRequest {
235
+ RecordRef subject = 1;
236
+ int32 limit = 2;
237
+ string cursor = 3;
238
+ }
239
+
240
+ message GetQuotesBySubjectSortedResponse {
241
+ repeated string uris = 1;
242
+ string cursor = 2;
243
+ }
244
+
223
245
  // - return like uris for user A on subject B, C, D...
224
246
  // - viewer state on posts
225
247
  message GetLikesByActorAndSubjectsRequest {
@@ -260,6 +282,7 @@ message GetInteractionCountsResponse {
260
282
  repeated int32 likes = 1;
261
283
  repeated int32 reposts = 2;
262
284
  repeated int32 replies = 3;
285
+ repeated int32 quotes = 4;
263
286
  }
264
287
 
265
288
  message GetCountsForUsersRequest {
@@ -293,6 +316,15 @@ message GetListCountsResponse {
293
316
  repeated int32 list_items = 1;
294
317
  }
295
318
 
319
+ message GetNewUserCountForRangeRequest {
320
+ google.protobuf.Timestamp start = 1;
321
+ google.protobuf.Timestamp end = 2;
322
+ }
323
+
324
+ message GetNewUserCountForRangeResponse {
325
+ int32 count = 1;
326
+ }
327
+
296
328
  //
297
329
  // Reposts
298
330
  //
@@ -568,7 +600,6 @@ message GetThreadMutesOnSubjectsResponse {
568
600
  repeated bool muted = 1;
569
601
  }
570
602
 
571
-
572
603
  //
573
604
  // Blocks
574
605
  //
@@ -1030,15 +1061,19 @@ message GetRecordTakedownResponse {
1030
1061
 
1031
1062
  // Polo-backed Graph Endpoints
1032
1063
 
1033
- // GetFollowsFollowing gets the list of DIDs that the actor follows that also follow the target
1064
+
1065
+
1066
+ // GetFollowsFollowing gets the list of DIDs that the actor follows that also follow the targets
1034
1067
  message GetFollowsFollowingRequest {
1035
1068
  string actor_did = 1;
1036
1069
  repeated string target_dids = 2;
1037
1070
  }
1071
+
1038
1072
  message FollowsFollowing {
1039
1073
  string target_did = 1;
1040
1074
  repeated string dids = 2;
1041
1075
  }
1076
+
1042
1077
  message GetFollowsFollowingResponse {
1043
1078
  repeated FollowsFollowing results = 1;
1044
1079
  }
@@ -1068,6 +1103,7 @@ service Service {
1068
1103
  rpc GetActorChatDeclarationRecords(GetActorChatDeclarationRecordsRequest) returns (GetActorChatDeclarationRecordsResponse);
1069
1104
  rpc GetRepostRecords(GetRepostRecordsRequest) returns (GetRepostRecordsResponse);
1070
1105
  rpc GetThreadGateRecords(GetThreadGateRecordsRequest) returns (GetThreadGateRecordsResponse);
1106
+ rpc GetPostgateRecords(GetPostgateRecordsRequest) returns (GetPostgateRecordsResponse);
1071
1107
  rpc GetLabelerRecords(GetLabelerRecordsRequest) returns (GetLabelerRecordsResponse);
1072
1108
  rpc GetStarterPackRecords(GetStarterPackRecordsRequest) returns (GetStarterPackRecordsResponse);
1073
1109
 
@@ -1087,11 +1123,15 @@ service Service {
1087
1123
  rpc GetRepostsByActorAndSubjects(GetRepostsByActorAndSubjectsRequest) returns (GetRepostsByActorAndSubjectsResponse);
1088
1124
  rpc GetActorReposts(GetActorRepostsRequest) returns (GetActorRepostsResponse);
1089
1125
 
1126
+ // Quotes
1127
+ rpc GetQuotesBySubjectSorted(GetQuotesBySubjectSortedRequest) returns (GetQuotesBySubjectSortedResponse);
1128
+
1090
1129
  // Interaction Counts
1091
1130
  rpc GetInteractionCounts(GetInteractionCountsRequest) returns (GetInteractionCountsResponse);
1092
1131
  rpc GetCountsForUsers(GetCountsForUsersRequest) returns (GetCountsForUsersResponse);
1093
1132
  rpc GetStarterPackCounts(GetStarterPackCountsRequest) returns (GetStarterPackCountsResponse);
1094
1133
  rpc GetListCounts(GetListCountsRequest) returns (GetListCountsResponse);
1134
+ rpc GetNewUserCountForRange(GetNewUserCountForRangeRequest) returns (GetNewUserCountForRangeResponse);
1095
1135
 
1096
1136
  // Profile
1097
1137
  rpc GetActors(GetActorsRequest) returns (GetActorsResponse);
@@ -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) {
@@ -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
 
@@ -7,12 +7,14 @@ import {
7
7
  HydrateCtx,
8
8
  HydrationState,
9
9
  Hydrator,
10
+ mergeStates,
10
11
  } from '../../../../hydration/hydrator'
11
12
  import { Views } from '../../../../views'
12
13
  import { DataPlaneClient } from '../../../../data-plane'
13
14
  import { mapDefined } from '@atproto/common'
14
15
  import { parseString } from '../../../../hydration/util'
15
16
  import { FeedItem } from '../../../../hydration/feed'
17
+ import { uriToDid } from '../../../../util/uris'
16
18
 
17
19
  export default function (server: Server, ctx: AppContext) {
18
20
  const getListFeed = createPipeline(
@@ -71,23 +73,34 @@ const hydration = async (inputs: {
71
73
  skeleton: Skeleton
72
74
  }): Promise<HydrationState> => {
73
75
  const { ctx, params, skeleton } = inputs
74
- return ctx.hydrator.hydrateFeedItems(skeleton.items, params.hydrateCtx)
76
+ const [feedItemsState, bidirectionalBlocks] = await Promise.all([
77
+ ctx.hydrator.hydrateFeedItems(skeleton.items, params.hydrateCtx),
78
+ getBlocks({ ctx, params, skeleton }),
79
+ ])
80
+ return mergeStates(feedItemsState, {
81
+ bidirectionalBlocks,
82
+ })
75
83
  }
76
84
 
77
85
  const noBlocksOrMutes = (inputs: {
78
86
  ctx: Context
87
+ params: Params
79
88
  skeleton: Skeleton
80
89
  hydration: HydrationState
81
90
  }): Skeleton => {
82
- const { ctx, skeleton, hydration } = inputs
91
+ const { ctx, params, skeleton, hydration } = inputs
83
92
  skeleton.items = skeleton.items.filter((item) => {
84
93
  const bam = ctx.views.feedItemBlocksAndMutes(item, hydration)
94
+ const creatorBlocks = hydration.bidirectionalBlocks?.get(
95
+ uriToDid(params.list),
96
+ )
85
97
  return (
86
98
  !bam.authorBlocked &&
87
99
  !bam.authorMuted &&
88
100
  !bam.originatorBlocked &&
89
101
  !bam.originatorMuted &&
90
- !bam.ancestorAuthorBlocked
102
+ !bam.ancestorAuthorBlocked &&
103
+ !creatorBlocks?.get(uriToDid(item.post.uri))
91
104
  )
92
105
  })
93
106
  return skeleton
@@ -105,6 +118,20 @@ const presentation = (inputs: {
105
118
  return { feed, cursor: skeleton.cursor }
106
119
  }
107
120
 
121
+ const getBlocks = async (input: {
122
+ ctx: Context
123
+ skeleton: Skeleton
124
+ params: Params
125
+ }) => {
126
+ const { ctx, skeleton, params } = input
127
+ const pairs: Map<string, string[]> = new Map()
128
+ pairs.set(
129
+ uriToDid(params.list),
130
+ skeleton.items.map((item) => uriToDid(item.post.uri)),
131
+ )
132
+ return await ctx.hydrator.hydrateBidirectionalBlocks(pairs)
133
+ }
134
+
108
135
  type Context = {
109
136
  hydrator: Hydrator
110
137
  views: Views
@@ -9,7 +9,7 @@ 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
14
  import { ids } from '../../../../lexicon/lexicons'
15
15
 
@@ -0,0 +1,108 @@
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 { 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 { uris: [] }
44
+ }
45
+ const quotesRes = await ctx.hydrator.dataplane.getQuotesBySubjectSorted({
46
+ subject: { uri: params.uri, cid: params.cid },
47
+ cursor: params.cursor,
48
+ limit: params.limit,
49
+ })
50
+ return {
51
+ uris: quotesRes.uris,
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(
63
+ skeleton.uris.map((uri) => ({ uri })),
64
+ params.hydrateCtx,
65
+ )
66
+ }
67
+
68
+ const noBlocks = (inputs: {
69
+ ctx: Context
70
+ skeleton: Skeleton
71
+ hydration: HydrationState
72
+ }) => {
73
+ const { ctx, skeleton, hydration } = inputs
74
+ skeleton.uris = skeleton.uris.filter((uri) => {
75
+ return !ctx.views.viewerBlockExists(uri, hydration)
76
+ })
77
+ return skeleton
78
+ }
79
+
80
+ const presentation = (inputs: {
81
+ ctx: Context
82
+ params: Params
83
+ skeleton: Skeleton
84
+ hydration: HydrationState
85
+ }) => {
86
+ const { ctx, params, skeleton, hydration } = inputs
87
+ const postViews = mapDefined(skeleton.uris, (uri) => {
88
+ return ctx.views.post(uri, hydration)
89
+ })
90
+ return {
91
+ posts: postViews,
92
+ cursor: skeleton.cursor,
93
+ uri: params.uri,
94
+ cid: params.cid,
95
+ }
96
+ }
97
+
98
+ type Context = {
99
+ hydrator: Hydrator
100
+ views: Views
101
+ }
102
+
103
+ type Params = QueryParams & { hydrateCtx: HydrateCtx }
104
+
105
+ type Skeleton = {
106
+ uris: string[]
107
+ cursor?: string
108
+ }
@@ -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,
@@ -19,7 +19,7 @@ import {
19
19
  import { Views } from '../../../../views'
20
20
  import { clearlyBadCursor, resHeaders } from '../../../util'
21
21
  import { ListItemInfo } from '../../../../proto/bsky_pb'
22
- import { didFromUri } from '../../../../hydration/util'
22
+ import { uriToDid as didFromUri } from '../../../../util/uris'
23
23
 
24
24
  export default function (server: Server, ctx: AppContext) {
25
25
  const getList = createPipeline(skeleton, hydration, noBlocks, presentation)
@@ -70,7 +70,7 @@ const hydration = async (
70
70
  params.hydrateCtx,
71
71
  ),
72
72
  ])
73
- const bidirectionalBlocks = await maybeGetBlocksForReferenceList({
73
+ const bidirectionalBlocks = await maybeGetBlocksForReferenceAndCurateList({
74
74
  ctx,
75
75
  params,
76
76
  skeleton,
@@ -106,7 +106,7 @@ const presentation = (
106
106
  return { list, items, cursor }
107
107
  }
108
108
 
109
- const maybeGetBlocksForReferenceList = async (input: {
109
+ const maybeGetBlocksForReferenceAndCurateList = async (input: {
110
110
  ctx: Context
111
111
  listState: HydrationState
112
112
  skeleton: SkeletonState
@@ -118,8 +118,8 @@ const maybeGetBlocksForReferenceList = async (input: {
118
118
  const listRecord = listState.lists?.get(list)
119
119
  const creator = didFromUri(list)
120
120
  if (
121
- listRecord?.record.purpose !== 'app.bsky.graph.defs#referencelist' ||
122
- params.hydrateCtx.viewer === creator
121
+ params.hydrateCtx.viewer === creator ||
122
+ listRecord?.record.purpose === 'app.bsky.graph.defs#modlist'
123
123
  ) {
124
124
  return
125
125
  }
@@ -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)
@@ -6,7 +6,8 @@ import * as post from './tables/post'
6
6
  import * as postEmbed from './tables/post-embed'
7
7
  import * as postAgg from './tables/post-agg'
8
8
  import * as repost from './tables/repost'
9
- import * as threadGate from './tables/thread-gate'
9
+ import * as threadgate from './tables/thread-gate'
10
+ import * as postgate from './tables/post-gate'
10
11
  import * as feedItem from './tables/feed-item'
11
12
  import * as follow from './tables/follow'
12
13
  import * as like from './tables/like'
@@ -35,6 +36,7 @@ import * as taggedSuggestion from './tables/tagged-suggestion'
35
36
  import * as blobTakedown from './tables/blob-takedown'
36
37
  import * as labeler from './tables/labeler'
37
38
  import * as starterPack from './tables/starter-pack'
39
+ import * as quote from './tables/quote'
38
40
 
39
41
  export type DatabaseSchemaType = duplicateRecord.PartialDB &
40
42
  profile.PartialDB &
@@ -43,7 +45,8 @@ export type DatabaseSchemaType = duplicateRecord.PartialDB &
43
45
  postEmbed.PartialDB &
44
46
  postAgg.PartialDB &
45
47
  repost.PartialDB &
46
- threadGate.PartialDB &
48
+ threadgate.PartialDB &
49
+ postgate.PartialDB &
47
50
  feedItem.PartialDB &
48
51
  follow.PartialDB &
49
52
  like.PartialDB &
@@ -71,7 +74,8 @@ export type DatabaseSchemaType = duplicateRecord.PartialDB &
71
74
  blobTakedown.PartialDB &
72
75
  labeler.PartialDB &
73
76
  starterPack.PartialDB &
74
- taggedSuggestion.PartialDB
77
+ taggedSuggestion.PartialDB &
78
+ quote.PartialDB
75
79
 
76
80
  export type DatabaseSchema = Kysely<DatabaseSchemaType>
77
81
 
@@ -0,0 +1,12 @@
1
+ import { Kysely } from 'kysely'
2
+
3
+ export async function up(db: Kysely<unknown>): Promise<void> {
4
+ await db.schema
5
+ .alterTable('post_agg')
6
+ .addColumn('quoteCount', 'bigint', (col) => col.notNull().defaultTo(0))
7
+ .execute()
8
+ }
9
+
10
+ export async function down(db: Kysely<unknown>): Promise<void> {
11
+ await db.schema.alterTable('post_agg').dropColumn('quoteCount').execute()
12
+ }