@atproto/bsky 0.0.273 → 0.0.274

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 (249) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/dist/api/app/bsky/actor/getSuggestions.d.ts.map +1 -1
  3. package/dist/api/app/bsky/actor/getSuggestions.js +7 -2
  4. package/dist/api/app/bsky/actor/getSuggestions.js.map +1 -1
  5. package/dist/api/app/bsky/actor/searchActors.d.ts.map +1 -1
  6. package/dist/api/app/bsky/actor/searchActors.js +13 -6
  7. package/dist/api/app/bsky/actor/searchActors.js.map +1 -1
  8. package/dist/api/app/bsky/bookmark/getBookmarks.d.ts.map +1 -1
  9. package/dist/api/app/bsky/bookmark/getBookmarks.js +7 -2
  10. package/dist/api/app/bsky/bookmark/getBookmarks.js.map +1 -1
  11. package/dist/api/app/bsky/contact/getMatches.d.ts.map +1 -1
  12. package/dist/api/app/bsky/contact/getMatches.js +8 -2
  13. package/dist/api/app/bsky/contact/getMatches.js.map +1 -1
  14. package/dist/api/app/bsky/feed/getActorFeeds.d.ts.map +1 -1
  15. package/dist/api/app/bsky/feed/getActorFeeds.js +7 -2
  16. package/dist/api/app/bsky/feed/getActorFeeds.js.map +1 -1
  17. package/dist/api/app/bsky/feed/getActorLikes.d.ts.map +1 -1
  18. package/dist/api/app/bsky/feed/getActorLikes.js +7 -2
  19. package/dist/api/app/bsky/feed/getActorLikes.js.map +1 -1
  20. package/dist/api/app/bsky/feed/getAuthorFeed.d.ts.map +1 -1
  21. package/dist/api/app/bsky/feed/getAuthorFeed.js +7 -2
  22. package/dist/api/app/bsky/feed/getAuthorFeed.js.map +1 -1
  23. package/dist/api/app/bsky/feed/getFeed.d.ts +13 -0
  24. package/dist/api/app/bsky/feed/getFeed.d.ts.map +1 -1
  25. package/dist/api/app/bsky/feed/getFeed.js +41 -8
  26. package/dist/api/app/bsky/feed/getFeed.js.map +1 -1
  27. package/dist/api/app/bsky/feed/getLikes.d.ts.map +1 -1
  28. package/dist/api/app/bsky/feed/getLikes.js +7 -2
  29. package/dist/api/app/bsky/feed/getLikes.js.map +1 -1
  30. package/dist/api/app/bsky/feed/getListFeed.d.ts.map +1 -1
  31. package/dist/api/app/bsky/feed/getListFeed.js +7 -2
  32. package/dist/api/app/bsky/feed/getListFeed.js.map +1 -1
  33. package/dist/api/app/bsky/feed/getQuotes.d.ts.map +1 -1
  34. package/dist/api/app/bsky/feed/getQuotes.js +7 -2
  35. package/dist/api/app/bsky/feed/getQuotes.js.map +1 -1
  36. package/dist/api/app/bsky/feed/getRepostedBy.d.ts.map +1 -1
  37. package/dist/api/app/bsky/feed/getRepostedBy.js +7 -2
  38. package/dist/api/app/bsky/feed/getRepostedBy.js.map +1 -1
  39. package/dist/api/app/bsky/feed/getSuggestedFeeds.d.ts.map +1 -1
  40. package/dist/api/app/bsky/feed/getSuggestedFeeds.js +20 -13
  41. package/dist/api/app/bsky/feed/getSuggestedFeeds.js.map +1 -1
  42. package/dist/api/app/bsky/feed/getTimeline.d.ts.map +1 -1
  43. package/dist/api/app/bsky/feed/getTimeline.js +7 -2
  44. package/dist/api/app/bsky/feed/getTimeline.js.map +1 -1
  45. package/dist/api/app/bsky/feed/searchPosts.d.ts.map +1 -1
  46. package/dist/api/app/bsky/feed/searchPosts.js +14 -7
  47. package/dist/api/app/bsky/feed/searchPosts.js.map +1 -1
  48. package/dist/api/app/bsky/feed/searchPostsV2.d.ts.map +1 -1
  49. package/dist/api/app/bsky/feed/searchPostsV2.js +17 -9
  50. package/dist/api/app/bsky/feed/searchPostsV2.js.map +1 -1
  51. package/dist/api/app/bsky/graph/getActorStarterPacks.d.ts.map +1 -1
  52. package/dist/api/app/bsky/graph/getActorStarterPacks.js +7 -2
  53. package/dist/api/app/bsky/graph/getActorStarterPacks.js.map +1 -1
  54. package/dist/api/app/bsky/graph/getBlocks.d.ts.map +1 -1
  55. package/dist/api/app/bsky/graph/getBlocks.js +7 -2
  56. package/dist/api/app/bsky/graph/getBlocks.js.map +1 -1
  57. package/dist/api/app/bsky/graph/getFollowers.d.ts.map +1 -1
  58. package/dist/api/app/bsky/graph/getFollowers.js +10 -18
  59. package/dist/api/app/bsky/graph/getFollowers.js.map +1 -1
  60. package/dist/api/app/bsky/graph/getFollows.d.ts.map +1 -1
  61. package/dist/api/app/bsky/graph/getFollows.js +7 -2
  62. package/dist/api/app/bsky/graph/getFollows.js.map +1 -1
  63. package/dist/api/app/bsky/graph/getList.d.ts.map +1 -1
  64. package/dist/api/app/bsky/graph/getList.js +7 -2
  65. package/dist/api/app/bsky/graph/getList.js.map +1 -1
  66. package/dist/api/app/bsky/graph/getListBlocks.d.ts.map +1 -1
  67. package/dist/api/app/bsky/graph/getListBlocks.js +7 -2
  68. package/dist/api/app/bsky/graph/getListBlocks.js.map +1 -1
  69. package/dist/api/app/bsky/graph/getListMutes.d.ts.map +1 -1
  70. package/dist/api/app/bsky/graph/getListMutes.js +7 -2
  71. package/dist/api/app/bsky/graph/getListMutes.js.map +1 -1
  72. package/dist/api/app/bsky/graph/getLists.d.ts.map +1 -1
  73. package/dist/api/app/bsky/graph/getLists.js +9 -4
  74. package/dist/api/app/bsky/graph/getLists.js.map +1 -1
  75. package/dist/api/app/bsky/graph/getListsWithMembership.d.ts.map +1 -1
  76. package/dist/api/app/bsky/graph/getListsWithMembership.js +9 -4
  77. package/dist/api/app/bsky/graph/getListsWithMembership.js.map +1 -1
  78. package/dist/api/app/bsky/graph/getMutes.d.ts.map +1 -1
  79. package/dist/api/app/bsky/graph/getMutes.js +22 -30
  80. package/dist/api/app/bsky/graph/getMutes.js.map +1 -1
  81. package/dist/api/app/bsky/graph/getStarterPacksWithMembership.d.ts.map +1 -1
  82. package/dist/api/app/bsky/graph/getStarterPacksWithMembership.js +7 -2
  83. package/dist/api/app/bsky/graph/getStarterPacksWithMembership.js.map +1 -1
  84. package/dist/api/app/bsky/graph/searchStarterPacks.d.ts.map +1 -1
  85. package/dist/api/app/bsky/graph/searchStarterPacks.js +13 -6
  86. package/dist/api/app/bsky/graph/searchStarterPacks.js.map +1 -1
  87. package/dist/api/app/bsky/graph/searchStarterPacksV2.d.ts.map +1 -1
  88. package/dist/api/app/bsky/graph/searchStarterPacksV2.js +7 -2
  89. package/dist/api/app/bsky/graph/searchStarterPacksV2.js.map +1 -1
  90. package/dist/api/app/bsky/notification/listActivitySubscriptions.d.ts.map +1 -1
  91. package/dist/api/app/bsky/notification/listActivitySubscriptions.js +7 -2
  92. package/dist/api/app/bsky/notification/listActivitySubscriptions.js.map +1 -1
  93. package/dist/api/app/bsky/notification/listNotifications.d.ts.map +1 -1
  94. package/dist/api/app/bsky/notification/listNotifications.js +17 -35
  95. package/dist/api/app/bsky/notification/listNotifications.js.map +1 -1
  96. package/dist/api/app/bsky/unspecced/getPopularFeedGenerators.d.ts.map +1 -1
  97. package/dist/api/app/bsky/unspecced/getPopularFeedGenerators.js +49 -43
  98. package/dist/api/app/bsky/unspecced/getPopularFeedGenerators.js.map +1 -1
  99. package/dist/api/app/bsky/unspecced/getTrendingTopics.d.ts.map +1 -1
  100. package/dist/api/app/bsky/unspecced/getTrendingTopics.js +3 -14
  101. package/dist/api/app/bsky/unspecced/getTrendingTopics.js.map +1 -1
  102. package/dist/api/app/bsky/unspecced/getTrends.d.ts.map +1 -1
  103. package/dist/api/app/bsky/unspecced/getTrends.js +3 -14
  104. package/dist/api/app/bsky/unspecced/getTrends.js.map +1 -1
  105. package/dist/api/util.d.ts +15 -0
  106. package/dist/api/util.d.ts.map +1 -1
  107. package/dist/api/util.js +26 -0
  108. package/dist/api/util.js.map +1 -1
  109. package/dist/config.d.ts +2 -0
  110. package/dist/config.d.ts.map +1 -1
  111. package/dist/config.js +5 -0
  112. package/dist/config.js.map +1 -1
  113. package/dist/data-plane/server/db/pagination.d.ts +8 -0
  114. package/dist/data-plane/server/db/pagination.d.ts.map +1 -1
  115. package/dist/data-plane/server/db/pagination.js +20 -2
  116. package/dist/data-plane/server/db/pagination.js.map +1 -1
  117. package/dist/data-plane/server/op-thread.d.ts +7 -0
  118. package/dist/data-plane/server/op-thread.d.ts.map +1 -0
  119. package/dist/data-plane/server/op-thread.js +71 -0
  120. package/dist/data-plane/server/op-thread.js.map +1 -0
  121. package/dist/data-plane/server/routes/activity-subscription.js +3 -3
  122. package/dist/data-plane/server/routes/activity-subscription.js.map +1 -1
  123. package/dist/data-plane/server/routes/blocks.js +6 -6
  124. package/dist/data-plane/server/routes/blocks.js.map +1 -1
  125. package/dist/data-plane/server/routes/bookmarks.js +3 -3
  126. package/dist/data-plane/server/routes/bookmarks.js.map +1 -1
  127. package/dist/data-plane/server/routes/drafts.js +3 -3
  128. package/dist/data-plane/server/routes/drafts.js.map +1 -1
  129. package/dist/data-plane/server/routes/feed-gens.js +14 -12
  130. package/dist/data-plane/server/routes/feed-gens.js.map +1 -1
  131. package/dist/data-plane/server/routes/feeds.d.ts.map +1 -1
  132. package/dist/data-plane/server/routes/feeds.js +36 -15
  133. package/dist/data-plane/server/routes/feeds.js.map +1 -1
  134. package/dist/data-plane/server/routes/follows.js +6 -6
  135. package/dist/data-plane/server/routes/follows.js.map +1 -1
  136. package/dist/data-plane/server/routes/likes.js +6 -6
  137. package/dist/data-plane/server/routes/likes.js.map +1 -1
  138. package/dist/data-plane/server/routes/lists.js +6 -6
  139. package/dist/data-plane/server/routes/lists.js.map +1 -1
  140. package/dist/data-plane/server/routes/mutes.js +7 -7
  141. package/dist/data-plane/server/routes/mutes.js.map +1 -1
  142. package/dist/data-plane/server/routes/notifs.js +3 -3
  143. package/dist/data-plane/server/routes/notifs.js.map +1 -1
  144. package/dist/data-plane/server/routes/quotes.js +3 -3
  145. package/dist/data-plane/server/routes/quotes.js.map +1 -1
  146. package/dist/data-plane/server/routes/records.d.ts +3 -1
  147. package/dist/data-plane/server/routes/records.d.ts.map +1 -1
  148. package/dist/data-plane/server/routes/records.js +41 -4
  149. package/dist/data-plane/server/routes/records.js.map +1 -1
  150. package/dist/data-plane/server/routes/reposts.js +6 -6
  151. package/dist/data-plane/server/routes/reposts.js.map +1 -1
  152. package/dist/data-plane/server/routes/search.js +9 -9
  153. package/dist/data-plane/server/routes/search.js.map +1 -1
  154. package/dist/data-plane/server/routes/starter-packs.js +3 -3
  155. package/dist/data-plane/server/routes/starter-packs.js.map +1 -1
  156. package/dist/data-plane/server/routes/threads.d.ts.map +1 -1
  157. package/dist/data-plane/server/routes/threads.js +3 -74
  158. package/dist/data-plane/server/routes/threads.js.map +1 -1
  159. package/dist/feature-gates/gates.d.ts +2 -1
  160. package/dist/feature-gates/gates.d.ts.map +1 -1
  161. package/dist/feature-gates/gates.js +2 -1
  162. package/dist/feature-gates/gates.js.map +1 -1
  163. package/dist/hydration/feed.d.ts +3 -0
  164. package/dist/hydration/feed.d.ts.map +1 -1
  165. package/dist/hydration/feed.js +12 -0
  166. package/dist/hydration/feed.js.map +1 -1
  167. package/dist/hydration/hydrator.d.ts.map +1 -1
  168. package/dist/hydration/hydrator.js +4 -2
  169. package/dist/hydration/hydrator.js.map +1 -1
  170. package/dist/image/server.d.ts +1 -1
  171. package/dist/image/server.d.ts.map +1 -1
  172. package/dist/image/server.js +40 -22
  173. package/dist/image/server.js.map +1 -1
  174. package/dist/lexicons/app/bsky/actor/contentVisibilityDeclaration.d.ts +3 -0
  175. package/dist/lexicons/app/bsky/actor/contentVisibilityDeclaration.d.ts.map +1 -0
  176. package/dist/lexicons/app/bsky/actor/contentVisibilityDeclaration.defs.d.ts +66 -0
  177. package/dist/lexicons/app/bsky/actor/contentVisibilityDeclaration.defs.d.ts.map +1 -0
  178. package/dist/lexicons/app/bsky/actor/contentVisibilityDeclaration.defs.js +26 -0
  179. package/dist/lexicons/app/bsky/actor/contentVisibilityDeclaration.defs.js.map +1 -0
  180. package/dist/lexicons/app/bsky/actor/contentVisibilityDeclaration.js +6 -0
  181. package/dist/lexicons/app/bsky/actor/contentVisibilityDeclaration.js.map +1 -0
  182. package/dist/lexicons/app/bsky/actor.d.ts +1 -0
  183. package/dist/lexicons/app/bsky/actor.d.ts.map +1 -1
  184. package/dist/lexicons/app/bsky/actor.js +1 -0
  185. package/dist/lexicons/app/bsky/actor.js.map +1 -1
  186. package/dist/lexicons/app/bsky/authCreatePosts.defs.d.ts.map +1 -1
  187. package/dist/lexicons/app/bsky/authCreatePosts.defs.js +5 -0
  188. package/dist/lexicons/app/bsky/authCreatePosts.defs.js.map +1 -1
  189. package/dist/lexicons/app/bsky/authFullApp.defs.d.ts.map +1 -1
  190. package/dist/lexicons/app/bsky/authFullApp.defs.js +5 -0
  191. package/dist/lexicons/app/bsky/authFullApp.defs.js.map +1 -1
  192. package/dist/lexicons/app/bsky/video/abortUpload.d.ts +3 -0
  193. package/dist/lexicons/app/bsky/video/abortUpload.d.ts.map +1 -0
  194. package/dist/lexicons/app/bsky/video/abortUpload.defs.d.ts +53 -0
  195. package/dist/lexicons/app/bsky/video/abortUpload.defs.d.ts.map +1 -0
  196. package/dist/lexicons/app/bsky/video/abortUpload.defs.js +26 -0
  197. package/dist/lexicons/app/bsky/video/abortUpload.defs.js.map +1 -0
  198. package/dist/lexicons/app/bsky/video/abortUpload.js +6 -0
  199. package/dist/lexicons/app/bsky/video/abortUpload.js.map +1 -0
  200. package/dist/lexicons/app/bsky/video/defs.defs.d.ts +1 -1
  201. package/dist/lexicons/app/bsky/video/defs.defs.d.ts.map +1 -1
  202. package/dist/lexicons/app/bsky/video/defs.defs.js.map +1 -1
  203. package/dist/lexicons/app/bsky/video/finishUpload.d.ts +3 -0
  204. package/dist/lexicons/app/bsky/video/finishUpload.d.ts.map +1 -0
  205. package/dist/lexicons/app/bsky/video/finishUpload.defs.d.ts +42 -0
  206. package/dist/lexicons/app/bsky/video/finishUpload.defs.d.ts.map +1 -0
  207. package/dist/lexicons/app/bsky/video/finishUpload.defs.js +30 -0
  208. package/dist/lexicons/app/bsky/video/finishUpload.defs.js.map +1 -0
  209. package/dist/lexicons/app/bsky/video/finishUpload.js +6 -0
  210. package/dist/lexicons/app/bsky/video/finishUpload.js.map +1 -0
  211. package/dist/lexicons/app/bsky/video/getUploadStatus.d.ts +3 -0
  212. package/dist/lexicons/app/bsky/video/getUploadStatus.d.ts.map +1 -0
  213. package/dist/lexicons/app/bsky/video/getUploadStatus.defs.d.ts +73 -0
  214. package/dist/lexicons/app/bsky/video/getUploadStatus.defs.d.ts.map +1 -0
  215. package/dist/lexicons/app/bsky/video/getUploadStatus.defs.js +30 -0
  216. package/dist/lexicons/app/bsky/video/getUploadStatus.defs.js.map +1 -0
  217. package/dist/lexicons/app/bsky/video/getUploadStatus.js +6 -0
  218. package/dist/lexicons/app/bsky/video/getUploadStatus.js.map +1 -0
  219. package/dist/lexicons/app/bsky/video/startUpload.d.ts +3 -0
  220. package/dist/lexicons/app/bsky/video/startUpload.d.ts.map +1 -0
  221. package/dist/lexicons/app/bsky/video/startUpload.defs.d.ts +63 -0
  222. package/dist/lexicons/app/bsky/video/startUpload.defs.d.ts.map +1 -0
  223. package/dist/lexicons/app/bsky/video/startUpload.defs.js +36 -0
  224. package/dist/lexicons/app/bsky/video/startUpload.defs.js.map +1 -0
  225. package/dist/lexicons/app/bsky/video/startUpload.js +6 -0
  226. package/dist/lexicons/app/bsky/video/startUpload.js.map +1 -0
  227. package/dist/lexicons/app/bsky/video/uploadPart.d.ts +3 -0
  228. package/dist/lexicons/app/bsky/video/uploadPart.d.ts.map +1 -0
  229. package/dist/lexicons/app/bsky/video/uploadPart.defs.d.ts +37 -0
  230. package/dist/lexicons/app/bsky/video/uploadPart.defs.d.ts.map +1 -0
  231. package/dist/lexicons/app/bsky/video/uploadPart.defs.js +31 -0
  232. package/dist/lexicons/app/bsky/video/uploadPart.defs.js.map +1 -0
  233. package/dist/lexicons/app/bsky/video/uploadPart.js +6 -0
  234. package/dist/lexicons/app/bsky/video/uploadPart.js.map +1 -0
  235. package/dist/lexicons/app/bsky/video.d.ts +5 -0
  236. package/dist/lexicons/app/bsky/video.d.ts.map +1 -1
  237. package/dist/lexicons/app/bsky/video.js +5 -0
  238. package/dist/lexicons/app/bsky/video.js.map +1 -1
  239. package/dist/proto/bsky_pb.d.ts +39 -0
  240. package/dist/proto/bsky_pb.d.ts.map +1 -1
  241. package/dist/proto/bsky_pb.js +55 -0
  242. package/dist/proto/bsky_pb.js.map +1 -1
  243. package/dist/views/index.d.ts.map +1 -1
  244. package/dist/views/index.js +2 -0
  245. package/dist/views/index.js.map +1 -1
  246. package/dist/views/types.d.ts +4 -1
  247. package/dist/views/types.d.ts.map +1 -1
  248. package/dist/views/types.js.map +1 -1
  249. package/package.json +10 -10
@@ -10,14 +10,7 @@ export default function (server, ctx) {
10
10
  handler: async ({ auth, params, req }) => {
11
11
  const viewer = auth.credentials.iss;
12
12
  const labelers = ctx.reqLabelers(req);
13
- const hydrateCtx = await ctx.hydrator.createContext({
14
- labelers,
15
- viewer,
16
- features: ctx.featureGatesClient.scope(ctx.featureGatesClient.parseUserContextFromHandler({
17
- viewer,
18
- req,
19
- })),
20
- });
13
+ const hydrateCtx = await ctx.hydrator.createContext({ labelers, viewer });
21
14
  const headers = noUndefinedVals({
22
15
  'accept-language': req.headers['accept-language'],
23
16
  'x-bsky-topics': Array.isArray(req.headers['x-bsky-topics'])
@@ -38,15 +31,11 @@ export default function (server, ctx) {
38
31
  }
39
32
  const skeleton = async (input) => {
40
33
  const { params, ctx } = input;
41
- // Route treatment users to iris (trending-topics v2), everyone else stays on
42
- // the existing hot-topic service.
43
- const useIris = params.hydrateCtx.features.checkGate(params.hydrateCtx.features.Gate.TrendingTopicsV2);
44
- const topicsClient = (useIris && ctx.irisClient) || ctx.topicsClient;
45
- if (!topicsClient) {
34
+ if (!ctx.irisClient) {
46
35
  // Use 501 instead of 500 as these are not considered retry-able by clients
47
36
  throw new MethodNotImplementedError('Topics agent not available');
48
37
  }
49
- const skeleton = await topicsClient.call(app.bsky.unspecced.getTrendsSkeleton, {
38
+ const skeleton = await ctx.irisClient.call(app.bsky.unspecced.getTrendsSkeleton, {
50
39
  limit: params.limit,
51
40
  viewer: params.hydrateCtx.viewer ?? undefined,
52
41
  }, {
@@ -1 +1 @@
1
- {"version":3,"file":"getTrends.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/unspecced/getTrends.ts"],"names":[],"mappings":"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","sourcesContent":["import { mapDefined, noUndefinedVals } from '@atproto/common'\nimport type { Client, DidString } from '@atproto/lex'\nimport { MethodNotImplementedError, type Server } from '@atproto/xrpc-server'\nimport type { AppContext } from '../../../../context.js'\nimport {\n type HydrateCtx,\n type Hydrator,\n mergeManyStates,\n} from '../../../../hydration/hydrator.js'\nimport { app } from '../../../../lexicons/index.js'\nimport {\n type HydrationFn,\n type PresentationFn,\n type RulesFn,\n type SkeletonFn,\n createPipeline,\n} from '../../../../pipeline.js'\nimport type { Views } from '../../../../views/index.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const getTrends = createPipeline(skeleton, hydration, noBlocks, presentation)\n server.add(app.bsky.unspecced.getTrends, {\n auth: ctx.authVerifier.standardOptional,\n handler: async ({ auth, params, req }) => {\n const viewer = auth.credentials.iss\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({\n labelers,\n viewer,\n features: ctx.featureGatesClient.scope(\n ctx.featureGatesClient.parseUserContextFromHandler({\n viewer,\n req,\n }),\n ),\n })\n const headers = noUndefinedVals({\n 'accept-language': req.headers['accept-language'],\n 'x-bsky-topics': Array.isArray(req.headers['x-bsky-topics'])\n ? req.headers['x-bsky-topics'].join(',')\n : req.headers['x-bsky-topics'],\n })\n const result = await getTrends(\n {\n ...params,\n hydrateCtx,\n headers,\n },\n ctx,\n )\n return {\n encoding: 'application/json',\n body: result,\n }\n },\n })\n}\n\nconst skeleton: SkeletonFn<Context, Params, SkeletonState> = async (input) => {\n const { params, ctx } = input\n\n // Route treatment users to iris (trending-topics v2), everyone else stays on\n // the existing hot-topic service.\n const useIris = params.hydrateCtx.features.checkGate(\n params.hydrateCtx.features.Gate.TrendingTopicsV2,\n )\n const topicsClient = (useIris && ctx.irisClient) || ctx.topicsClient\n\n if (!topicsClient) {\n // Use 501 instead of 500 as these are not considered retry-able by clients\n throw new MethodNotImplementedError('Topics agent not available')\n }\n\n const skeleton = await topicsClient.call(\n app.bsky.unspecced.getTrendsSkeleton,\n {\n limit: params.limit,\n viewer: params.hydrateCtx.viewer ?? undefined,\n },\n {\n headers: params.headers,\n },\n )\n\n // @TODO Make sure upstream always provides this\n for (const trend of skeleton.trends) trend.dids ??= []\n\n return skeleton\n}\n\nconst hydration: HydrationFn<Context, Params, SkeletonState> = async (\n input,\n) => {\n const { ctx, params, skeleton } = input\n const dids = getUniqueDidsFromTrends(skeleton.trends)\n const pairs: Map<DidString, DidString[]> = new Map()\n const viewer = params.hydrateCtx.viewer\n if (viewer) pairs.set(viewer, dids)\n\n const [profileState, bidirectionalBlocks] = await Promise.all([\n ctx.hydrator.hydrateProfilesBasic(dids, params.hydrateCtx),\n ctx.hydrator.hydrateBidirectionalBlocks(pairs, params.hydrateCtx),\n ])\n\n return mergeManyStates(profileState, { bidirectionalBlocks })\n}\n\nconst noBlocks: RulesFn<Context, Params, SkeletonState> = (input) => {\n const { skeleton, params, hydration } = input\n const viewer = params.hydrateCtx.viewer\n if (!viewer) {\n return skeleton\n }\n\n const blocks = hydration.bidirectionalBlocks?.get(viewer)\n\n return {\n recIdStr: skeleton.recIdStr,\n trends: skeleton.trends.map((t) => ({\n ...t,\n dids: t.dids.filter((did) => !blocks?.get(did)),\n })),\n }\n}\n\nconst presentation: PresentationFn<\n Context,\n Params,\n SkeletonState,\n app.bsky.unspecced.getTrends.$OutputBody\n> = (input) => {\n const { ctx, skeleton, hydration } = input\n\n return {\n recIdStr: skeleton.recIdStr,\n trends: skeleton.trends.map((t) => ({\n topic: t.topic,\n displayName: t.displayName,\n description: t.description,\n link: t.link,\n startedAt: t.startedAt,\n postCount: t.postCount,\n status: t.status,\n category: t.category,\n actors: mapDefined(t.dids, (did) =>\n ctx.views.profileBasic(did, hydration),\n ),\n })),\n }\n}\n\ntype Context = {\n hydrator: Hydrator\n views: Views\n topicsClient: Client | undefined\n irisClient: Client | undefined\n}\n\ntype Params = app.bsky.unspecced.getTrendingTopics.$Params & {\n hydrateCtx: HydrateCtx & { viewer: string | null }\n headers: Record<string, string>\n}\n\ntype SkeletonState = app.bsky.unspecced.getTrendsSkeleton.$OutputBody\n\nfunction getUniqueDidsFromTrends(\n trends?: app.bsky.unspecced.defs.SkeletonTrend[],\n): DidString[] {\n if (!trends) return []\n\n const dids = new Set<DidString>()\n\n for (const trend of trends) {\n if (trend.dids) {\n for (const did of trend.dids) {\n dids.add(did)\n }\n }\n }\n\n return Array.from(dids)\n}\n"]}
1
+ {"version":3,"file":"getTrends.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/unspecced/getTrends.ts"],"names":[],"mappings":"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","sourcesContent":["import { mapDefined, noUndefinedVals } from '@atproto/common'\nimport type { Client, DidString } from '@atproto/lex'\nimport { MethodNotImplementedError, type Server } from '@atproto/xrpc-server'\nimport type { AppContext } from '../../../../context.js'\nimport {\n type HydrateCtx,\n type Hydrator,\n mergeManyStates,\n} from '../../../../hydration/hydrator.js'\nimport { app } from '../../../../lexicons/index.js'\nimport {\n type HydrationFn,\n type PresentationFn,\n type RulesFn,\n type SkeletonFn,\n createPipeline,\n} from '../../../../pipeline.js'\nimport type { Views } from '../../../../views/index.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const getTrends = createPipeline(skeleton, hydration, noBlocks, presentation)\n server.add(app.bsky.unspecced.getTrends, {\n auth: ctx.authVerifier.standardOptional,\n handler: async ({ auth, params, req }) => {\n const viewer = auth.credentials.iss\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({ labelers, viewer })\n const headers = noUndefinedVals({\n 'accept-language': req.headers['accept-language'],\n 'x-bsky-topics': Array.isArray(req.headers['x-bsky-topics'])\n ? req.headers['x-bsky-topics'].join(',')\n : req.headers['x-bsky-topics'],\n })\n const result = await getTrends(\n {\n ...params,\n hydrateCtx,\n headers,\n },\n ctx,\n )\n return {\n encoding: 'application/json',\n body: result,\n }\n },\n })\n}\n\nconst skeleton: SkeletonFn<Context, Params, SkeletonState> = async (input) => {\n const { params, ctx } = input\n\n if (!ctx.irisClient) {\n // Use 501 instead of 500 as these are not considered retry-able by clients\n throw new MethodNotImplementedError('Topics agent not available')\n }\n\n const skeleton = await ctx.irisClient.call(\n app.bsky.unspecced.getTrendsSkeleton,\n {\n limit: params.limit,\n viewer: params.hydrateCtx.viewer ?? undefined,\n },\n {\n headers: params.headers,\n },\n )\n\n // @TODO Make sure upstream always provides this\n for (const trend of skeleton.trends) trend.dids ??= []\n\n return skeleton\n}\n\nconst hydration: HydrationFn<Context, Params, SkeletonState> = async (\n input,\n) => {\n const { ctx, params, skeleton } = input\n const dids = getUniqueDidsFromTrends(skeleton.trends)\n const pairs: Map<DidString, DidString[]> = new Map()\n const viewer = params.hydrateCtx.viewer\n if (viewer) pairs.set(viewer, dids)\n\n const [profileState, bidirectionalBlocks] = await Promise.all([\n ctx.hydrator.hydrateProfilesBasic(dids, params.hydrateCtx),\n ctx.hydrator.hydrateBidirectionalBlocks(pairs, params.hydrateCtx),\n ])\n\n return mergeManyStates(profileState, { bidirectionalBlocks })\n}\n\nconst noBlocks: RulesFn<Context, Params, SkeletonState> = (input) => {\n const { skeleton, params, hydration } = input\n const viewer = params.hydrateCtx.viewer\n if (!viewer) {\n return skeleton\n }\n\n const blocks = hydration.bidirectionalBlocks?.get(viewer)\n\n return {\n recIdStr: skeleton.recIdStr,\n trends: skeleton.trends.map((t) => ({\n ...t,\n dids: t.dids.filter((did) => !blocks?.get(did)),\n })),\n }\n}\n\nconst presentation: PresentationFn<\n Context,\n Params,\n SkeletonState,\n app.bsky.unspecced.getTrends.$OutputBody\n> = (input) => {\n const { ctx, skeleton, hydration } = input\n\n return {\n recIdStr: skeleton.recIdStr,\n trends: skeleton.trends.map((t) => ({\n topic: t.topic,\n displayName: t.displayName,\n description: t.description,\n link: t.link,\n startedAt: t.startedAt,\n postCount: t.postCount,\n status: t.status,\n category: t.category,\n actors: mapDefined(t.dids, (did) =>\n ctx.views.profileBasic(did, hydration),\n ),\n })),\n }\n}\n\ntype Context = {\n hydrator: Hydrator\n views: Views\n irisClient: Client | undefined\n}\n\ntype Params = app.bsky.unspecced.getTrendingTopics.$Params & {\n hydrateCtx: HydrateCtx & { viewer: string | null }\n headers: Record<string, string>\n}\n\ntype SkeletonState = app.bsky.unspecced.getTrendsSkeleton.$OutputBody\n\nfunction getUniqueDidsFromTrends(\n trends?: app.bsky.unspecced.defs.SkeletonTrend[],\n): DidString[] {\n if (!trends) return []\n\n const dids = new Set<DidString>()\n\n for (const trend of trends) {\n if (trend.dids) {\n for (const did of trend.dids) {\n dids.add(did)\n }\n }\n }\n\n return Array.from(dids)\n}\n"]}
@@ -10,6 +10,21 @@ type ResHeaderOpts = {
10
10
  };
11
11
  export declare const resHeaders: (opts: Partial<ResHeaderOpts>) => Record<string, string>;
12
12
  export declare const clearlyBadCursor: (cursor?: string) => boolean;
13
+ type PageFetch<R extends {
14
+ cursor?: string;
15
+ }> = (params: {
16
+ cursor?: string;
17
+ limit: number;
18
+ }) => Promise<R>;
19
+ export declare const fillPage: <F extends PageFetch<{
20
+ cursor?: string;
21
+ }>, T>(opts: {
22
+ cursor?: string;
23
+ limit: number;
24
+ maxRequests?: number;
25
+ fetch: F;
26
+ items: (result: Awaited<ReturnType<F>>) => T[];
27
+ }) => Promise<Awaited<ReturnType<F>>>;
13
28
  export declare const resolveSearchV2Override: (req: {
14
29
  headers: IncomingHttpHeaders;
15
30
  }, cfg: ServerConfig) => boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../src/api/util.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAA;AACpD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAChD,OAAO,EAAE,KAAK,cAAc,EAAuB,MAAM,YAAY,CAAA;AAErE,eAAO,MAAM,eAAe,gBAAgB,CAAA;AAC5C,eAAO,MAAM,wBAAwB,6BAA6B,CAAA;AAClE,eAAO,MAAM,gBAAgB,qBAAqB,CAAA;AAElD,KAAK,aAAa,GAAG;IACnB,QAAQ,EAAE,cAAc,CAAA;IACxB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;CACvB,CAAA;AAED,eAAO,MAAM,UAAU,SACf,OAAO,CAAC,aAAa,CAAC,KAC3B,MAAM,CAAC,MAAM,EAAE,MAAM,CASvB,CAAA;AAED,eAAO,MAAM,gBAAgB,YAAa,MAAM,YAG/C,CAAA;AAMD,eAAO,MAAM,uBAAuB,QAC7B;IAAE,OAAO,EAAE,mBAAmB,CAAA;CAAE,OAChC,YAAY,KAChB,OAMF,CAAA"}
1
+ {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../src/api/util.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAA;AACpD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAChD,OAAO,EAAE,KAAK,cAAc,EAAuB,MAAM,YAAY,CAAA;AAErE,eAAO,MAAM,eAAe,gBAAgB,CAAA;AAC5C,eAAO,MAAM,wBAAwB,6BAA6B,CAAA;AAClE,eAAO,MAAM,gBAAgB,qBAAqB,CAAA;AAElD,KAAK,aAAa,GAAG;IACnB,QAAQ,EAAE,cAAc,CAAA;IACxB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;CACvB,CAAA;AAED,eAAO,MAAM,UAAU,SACf,OAAO,CAAC,aAAa,CAAC,KAC3B,MAAM,CAAC,MAAM,EAAE,MAAM,CASvB,CAAA;AAED,eAAO,MAAM,gBAAgB,YAAa,MAAM,YAG/C,CAAA;AAID,KAAK,SAAS,CAAC,CAAC,SAAS;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,IAAI,CAAC,MAAM,EAAE;IACvD,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,MAAM,CAAA;CACd,KAAK,OAAO,CAAC,CAAC,CAAC,CAAA;AAEhB,eAAO,MAAM,QAAQ,GACnB,CAAC,SAAS,SAAS,CAAC;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,EACxC,CAAC,QACK;IACN,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,KAAK,EAAE,CAAC,CAAA;IACR,KAAK,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAA;CAC/C,KAAG,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CA2BjC,CAAA;AAMD,eAAO,MAAM,uBAAuB,QAC7B;IAAE,OAAO,EAAE,mBAAmB,CAAA;CAAE,OAChC,YAAY,KAChB,OAMF,CAAA"}
package/dist/api/util.js CHANGED
@@ -16,6 +16,32 @@ export const clearlyBadCursor = (cursor) => {
16
16
  // hallmark of v1 cursor, highly unlikely in v2 cursors based on time or rkeys
17
17
  return !!cursor?.includes('::');
18
18
  };
19
+ const DEFAULT_FILL_PAGE_MAX_REQUESTS = 10;
20
+ export const fillPage = async (opts) => {
21
+ const maxRequests = opts.maxRequests ?? DEFAULT_FILL_PAGE_MAX_REQUESTS;
22
+ const result = (await opts.fetch({
23
+ cursor: opts.cursor,
24
+ limit: opts.limit,
25
+ }));
26
+ const items = opts.items(result);
27
+ let cursor = result.cursor;
28
+ for (let requests = 1; requests < maxRequests && cursor && items.length < opts.limit; requests++) {
29
+ const previousCursor = cursor;
30
+ const page = (await opts.fetch({
31
+ cursor,
32
+ limit: opts.limit - items.length,
33
+ }));
34
+ items.push(...opts.items(page));
35
+ cursor = page.cursor;
36
+ if (cursor === previousCursor) {
37
+ cursor = undefined;
38
+ break;
39
+ }
40
+ if (!cursor)
41
+ break;
42
+ }
43
+ return { ...result, cursor };
44
+ };
19
45
  // @TEMPORARY backdoor to force search v2 via a request header, gated by the
20
46
  // BSKY_SEARCH_V2_OVERRIDE_HEADER env var. Remove once search v2 is fully rolled out.
21
47
  const SEARCH_V2_OVERRIDE_HEADER = 'x-bsky-search-v2-override';
@@ -1 +1 @@
1
- {"version":3,"file":"util.js","sourceRoot":"","sources":["../../src/api/util.ts"],"names":[],"mappings":"AAEA,OAAO,EAAuB,mBAAmB,EAAE,MAAM,YAAY,CAAA;AAErE,MAAM,CAAC,MAAM,eAAe,GAAG,aAAa,CAAA;AAC5C,MAAM,CAAC,MAAM,wBAAwB,GAAG,0BAA0B,CAAA;AAClE,MAAM,CAAC,MAAM,gBAAgB,GAAG,kBAAkB,CAAA;AAOlD,MAAM,CAAC,MAAM,UAAU,GAAG,CACxB,IAA4B,EACJ,EAAE;IAC1B,MAAM,OAAO,GAAG,EAAE,CAAA;IAClB,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAClB,OAAO,CAAC,wBAAwB,CAAC,GAAG,mBAAmB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;IACxE,CAAC;IACD,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;QACjB,OAAO,CAAC,gBAAgB,CAAC,GAAG,IAAI,CAAC,OAAO,CAAA;IAC1C,CAAC;IACD,OAAO,OAAO,CAAA;AAChB,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,MAAe,EAAE,EAAE;IAClD,8EAA8E;IAC9E,OAAO,CAAC,CAAC,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAA;AACjC,CAAC,CAAA;AAED,4EAA4E;AAC5E,qFAAqF;AACrF,MAAM,yBAAyB,GAAG,2BAA2B,CAAA;AAE7D,MAAM,CAAC,MAAM,uBAAuB,GAAG,CACrC,GAAqC,EACrC,GAAiB,EACR,EAAE;IACX,MAAM,QAAQ,GAAG,GAAG,CAAC,sBAAsB,CAAA;IAC3C,IAAI,CAAC,QAAQ;QAAE,OAAO,KAAK,CAAA;IAC3B,MAAM,KAAK,GAAG,GAAG,CAAC,OAAO,CAAC,yBAAyB,CAAC,CAAA;IACpD,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAA;IAC7D,OAAO,MAAM,KAAK,QAAQ,CAAA;AAC5B,CAAC,CAAA","sourcesContent":["import type { IncomingHttpHeaders } from 'node:http'\nimport type { ServerConfig } from '../config.js'\nimport { type ParsedLabelers, formatLabelerHeader } from '../util.js'\n\nexport const BSKY_USER_AGENT = 'BskyAppView'\nexport const ATPROTO_CONTENT_LABELERS = 'Atproto-Content-Labelers'\nexport const ATPROTO_REPO_REV = 'Atproto-Repo-Rev'\n\ntype ResHeaderOpts = {\n labelers: ParsedLabelers\n repoRev: string | null\n}\n\nexport const resHeaders = (\n opts: Partial<ResHeaderOpts>,\n): Record<string, string> => {\n const headers = {}\n if (opts.labelers) {\n headers[ATPROTO_CONTENT_LABELERS] = formatLabelerHeader(opts.labelers)\n }\n if (opts.repoRev) {\n headers[ATPROTO_REPO_REV] = opts.repoRev\n }\n return headers\n}\n\nexport const clearlyBadCursor = (cursor?: string) => {\n // hallmark of v1 cursor, highly unlikely in v2 cursors based on time or rkeys\n return !!cursor?.includes('::')\n}\n\n// @TEMPORARY backdoor to force search v2 via a request header, gated by the\n// BSKY_SEARCH_V2_OVERRIDE_HEADER env var. Remove once search v2 is fully rolled out.\nconst SEARCH_V2_OVERRIDE_HEADER = 'x-bsky-search-v2-override'\n\nexport const resolveSearchV2Override = (\n req: { headers: IncomingHttpHeaders },\n cfg: ServerConfig,\n): boolean => {\n const expected = cfg.searchV2OverrideHeader\n if (!expected) return false\n const value = req.headers[SEARCH_V2_OVERRIDE_HEADER]\n const header = Array.isArray(value) ? value.join(',') : value\n return header === expected\n}\n"]}
1
+ {"version":3,"file":"util.js","sourceRoot":"","sources":["../../src/api/util.ts"],"names":[],"mappings":"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","sourcesContent":["import type { IncomingHttpHeaders } from 'node:http'\nimport type { ServerConfig } from '../config.js'\nimport { type ParsedLabelers, formatLabelerHeader } from '../util.js'\n\nexport const BSKY_USER_AGENT = 'BskyAppView'\nexport const ATPROTO_CONTENT_LABELERS = 'Atproto-Content-Labelers'\nexport const ATPROTO_REPO_REV = 'Atproto-Repo-Rev'\n\ntype ResHeaderOpts = {\n labelers: ParsedLabelers\n repoRev: string | null\n}\n\nexport const resHeaders = (\n opts: Partial<ResHeaderOpts>,\n): Record<string, string> => {\n const headers = {}\n if (opts.labelers) {\n headers[ATPROTO_CONTENT_LABELERS] = formatLabelerHeader(opts.labelers)\n }\n if (opts.repoRev) {\n headers[ATPROTO_REPO_REV] = opts.repoRev\n }\n return headers\n}\n\nexport const clearlyBadCursor = (cursor?: string) => {\n // hallmark of v1 cursor, highly unlikely in v2 cursors based on time or rkeys\n return !!cursor?.includes('::')\n}\n\nconst DEFAULT_FILL_PAGE_MAX_REQUESTS = 10\n\ntype PageFetch<R extends { cursor?: string }> = (params: {\n cursor?: string\n limit: number\n}) => Promise<R>\n\nexport const fillPage = async <\n F extends PageFetch<{ cursor?: string }>,\n T,\n>(opts: {\n cursor?: string\n limit: number\n maxRequests?: number\n fetch: F\n items: (result: Awaited<ReturnType<F>>) => T[]\n}): Promise<Awaited<ReturnType<F>>> => {\n const maxRequests = opts.maxRequests ?? DEFAULT_FILL_PAGE_MAX_REQUESTS\n const result = (await opts.fetch({\n cursor: opts.cursor,\n limit: opts.limit,\n })) as Awaited<ReturnType<F>>\n const items = opts.items(result)\n let cursor = result.cursor\n for (\n let requests = 1;\n requests < maxRequests && cursor && items.length < opts.limit;\n requests++\n ) {\n const previousCursor = cursor\n const page = (await opts.fetch({\n cursor,\n limit: opts.limit - items.length,\n })) as Awaited<ReturnType<F>>\n items.push(...opts.items(page))\n cursor = page.cursor\n if (cursor === previousCursor) {\n cursor = undefined\n break\n }\n if (!cursor) break\n }\n return { ...result, cursor } as Awaited<ReturnType<F>>\n}\n\n// @TEMPORARY backdoor to force search v2 via a request header, gated by the\n// BSKY_SEARCH_V2_OVERRIDE_HEADER env var. Remove once search v2 is fully rolled out.\nconst SEARCH_V2_OVERRIDE_HEADER = 'x-bsky-search-v2-override'\n\nexport const resolveSearchV2Override = (\n req: { headers: IncomingHttpHeaders },\n cfg: ServerConfig,\n): boolean => {\n const expected = cfg.searchV2OverrideHeader\n if (!expected) return false\n const value = req.headers[SEARCH_V2_OVERRIDE_HEADER]\n const header = Array.isArray(value) ? value.join(',') : value\n return header === expected\n}\n"]}
package/dist/config.d.ts CHANGED
@@ -61,6 +61,7 @@ export interface ServerConfigValues {
61
61
  topicsUrl?: string;
62
62
  topicsApiKey?: string;
63
63
  irisUrl?: string;
64
+ irisFeedUris?: Set<string>;
64
65
  cdnUrl?: string;
65
66
  videoPlaylistUrlPattern?: string;
66
67
  videoThumbnailUrlPattern?: string;
@@ -138,6 +139,7 @@ export declare class ServerConfig {
138
139
  get topicsUrl(): string | undefined;
139
140
  get topicsApiKey(): string | undefined;
140
141
  get irisUrl(): string | undefined;
142
+ get irisFeedUris(): Set<string> | undefined;
141
143
  get cdnUrl(): string | undefined;
142
144
  get videoPlaylistUrlPattern(): string | undefined;
143
145
  get videoThumbnailUrlPattern(): string | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,SAAS,EAAe,MAAM,cAAc,CAAA;AAG1D,KAAK,aAAa,GAAG;IACnB,GAAG,EAAE,SAAS,CAAA;IACd,OAAO,EAAE,MAAM,EAAE,CAAA;CAClB,EAAE,CAAA;AAEH,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;IACjB;;OAEG;IACH,kBAAkB,EAAE,MAAM,CAAA;IAC1B;;OAEG;IACH,aAAa,EAAE,MAAM,CAAA;IACrB;;OAEG;IACH,wBAAwB,EAAE,MAAM,CAAA;IAChC;;OAEG;IACH,yBAAyB,EAAE,MAAM,CAAA;CAClC;AAED,MAAM,WAAW,kBAAkB;IAEjC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,SAAS,CAAA;IACpB,qBAAqB,EAAE,SAAS,EAAE,CAAA;IAClC,uBAAuB,CAAC,EAAE,MAAM,CAAA;IAChC,aAAa,CAAC,EAAE,aAAa,CAAA;IAE7B,SAAS,EAAE,MAAM,EAAE,CAAA;IACnB,aAAa,EAAE,MAAM,EAAE,CAAA;IACvB,0BAA0B,CAAC,EAAE,MAAM,CAAA;IACnC,oBAAoB,CAAC,EAAE,KAAK,GAAG,GAAG,CAAA;IAClC,qBAAqB,CAAC,EAAE,OAAO,CAAA;IAC/B,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,gBAAgB,CAAC,EAAE,KAAK,GAAG,GAAG,CAAA;IAC9B,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,kBAAkB,CAAC,EAAE,KAAK,GAAG,GAAG,CAAA;IAChC,mBAAmB,CAAC,EAAE,OAAO,CAAA;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,kBAAkB,CAAC,EAAE,KAAK,GAAG,GAAG,CAAA;IAChC,mBAAmB,CAAC,EAAE,OAAO,CAAA;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAC3B,iBAAiB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAC9B,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,YAAY,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,uBAAuB,CAAC,EAAE,MAAM,CAAA;IAChC,wBAAwB,CAAC,EAAE,MAAM,CAAA;IACjC,sBAAsB,CAAC,EAAE,MAAM,CAAA;IAC/B,2BAA2B,CAAC,EAAE,MAAM,CAAA;IAEpC,SAAS,EAAE,MAAM,CAAA;IACjB,wBAAwB,CAAC,EAAE,MAAM,EAAE,CAAA;IAEnC,aAAa,EAAE,SAAS,CAAA;IACxB,cAAc,EAAE,MAAM,EAAE,CAAA;IACxB,oBAAoB,CAAC,EAAE,SAAS,EAAE,CAAA;IAClC,cAAc,CAAC,EAAE,IAAI,CAAA;IAErB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,0BAA0B,CAAC,EAAE,MAAM,CAAA;IACnC,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAE5B,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,gBAAgB,EAAE,MAAM,CAAA;IACxB,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAC3B,kBAAkB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAC/B,iBAAiB,EAAE,MAAM,CAAA;IACzB,uBAAuB,EAAE,MAAM,CAAA;IAE/B,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAE7B,yBAAyB,CAAC,EAAE,OAAO,CAAA;IACnC,aAAa,CAAC,EAAE,OAAO,CAAA;IAEvB,qBAAqB,CAAC,EAAE,OAAO,CAAA;IAC/B,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,qBAAqB,CAAC,EAAE,OAAO,CAAA;IAC/B,GAAG,CAAC,EAAE,SAAS,CAAA;IACf,qBAAqB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAClC,WAAW,EAAE,MAAM,CAAA;IACnB,sBAAsB,CAAC,EAAE,MAAM,CAAA;CAChC;AAED,qBAAa,YAAY;IAEX,OAAO,CAAC,GAAG;IADvB,OAAO,CAAC,YAAY,CAAC,CAAQ;IAC7B,YAAoB,GAAG,EAAE,kBAAkB,EAAI;IAE/C,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,gBA4SrD;IAED,UAAU,CAAC,IAAI,EAAE,MAAM,QAMtB;IAED,IAAI,OAAO,uBAEV;IAED,IAAI,SAAS,YAEZ;IAED,IAAI,IAAI,uBAEP;IAED,IAAI,SAAS,uBAEZ;IAED,IAAI,SAAS,8BAEZ;IAED,IAAI,qBAAqB,gCAExB;IAED,IAAI,uBAAuB,uBAE1B;IAED,IAAI,aAAa,8BAEhB;IAED,IAAI,SAAS,aAEZ;IAED,IAAI,0BAA0B,uBAE7B;IAED,IAAI,aAAa,aAEhB;IAED,IAAI,oBAAoB,4BAEvB;IAED,IAAI,qBAAqB,wBAExB;IAED,IAAI,QAAQ,WAEX;IAED,IAAI,WAAW,uBAEd;IAED,IAAI,gBAAgB,4BAEnB;IAED,IAAI,iBAAiB,wBAEpB;IAED,IAAI,UAAU,uBAEb;IAED,IAAI,aAAa,uBAEhB;IAED,IAAI,kBAAkB,4BAErB;IAED,IAAI,mBAAmB,wBAEtB;IAED,IAAI,UAAU,uBAEb;IACD,IAAI,aAAa,uBAEhB;IACD,IAAI,kBAAkB,4BAErB;IACD,IAAI,mBAAmB,wBAEtB;IAED,IAAI,SAAS,uBAEZ;IAED,IAAI,cAAc,gBAEjB;IAED,IAAI,iBAAiB,gBAEpB;IAED,IAAI,cAAc,uBAEjB;IAED,IAAI,iBAAiB,uBAEpB;IAED,IAAI,SAAS,uBAEZ;IAED,IAAI,YAAY,uBAEf;IAED,IAAI,OAAO,uBAEV;IAED,IAAI,YAAY,4BAEf;IAED,IAAI,MAAM,uBAET;IAED,IAAI,uBAAuB,uBAE1B;IAED,IAAI,wBAAwB,uBAE3B;IAED,IAAI,sBAAsB,uBAEzB;IAED,IAAI,2BAA2B,uBAE9B;IAED,IAAI,SAAS,WAEZ;IAED,IAAI,wBAAwB,yBAE3B;IAED,IAAI,cAAc,aAEjB;IAED,IAAI,aAAa,8BAEhB;IAED,IAAI,oBAAoB,IAC0B,SAAS,EAAE,CAC5D;IAED,IAAI,iBAAiB,uBAEpB;IAED,IAAI,0BAA0B,uBAE7B;IAED,IAAI,iBAAiB,uBAEpB;IAED,IAAI,mBAAmB,uBAEtB;IAED,IAAI,yBAAyB,wBAE5B;IAED,IAAI,aAAa,wBAEhB;IAED,IAAI,cAAc,qBAEjB;IAED,IAAI,aAAa,gBAEhB;IAED,IAAI,cAAc,uBAEjB;IAED,IAAI,cAAc,uBAEjB;IAED,IAAI,gBAAgB,WAEnB;IAED,IAAI,cAAc,gBAEjB;IAED,IAAI,kBAAkB,gBAErB;IAED,IAAI,iBAAiB,WAEpB;IAED,IAAI,uBAAuB,WAE1B;IAED,IAAI,oBAAoB,WAEvB;IAED,IAAI,qBAAqB,IAAI,OAAO,CAEnC;IAED,IAAI,eAAe,IAAI,OAAO,CAE7B;IAED,IAAI,mBAAmB,IAAI,MAAM,CAEhC;IAED,IAAI,gBAAgB,IAAI,MAAM,CAE7B;IAED,IAAI,oBAAoB,IAAI,MAAM,CAEjC;IAED,IAAI,eAAe,IAAI,MAAM,CAE5B;IAED,IAAI,qBAAqB,IAAI,OAAO,CAEnC;IAED,IAAI,GAAG,0BAEN;IAED,IAAI,qBAAqB,gBAExB;IAED,IAAI,WAAW,WAEd;IAED,IAAI,sBAAsB,uBAEzB;CACF"}
package/dist/config.js CHANGED
@@ -54,6 +54,7 @@ export class ServerConfig {
54
54
  const topicsUrl = process.env.BSKY_TOPICS_URL || undefined;
55
55
  const topicsApiKey = process.env.BSKY_TOPICS_API_KEY;
56
56
  const irisUrl = process.env.BSKY_IRIS_URL || undefined;
57
+ const irisFeedUris = new Set(envList(process.env.BSKY_IRIS_FEED_URIS));
57
58
  const dataplaneUrls = overrides?.dataplaneUrls ?? envList(process.env.BSKY_DATAPLANE_URLS);
58
59
  const dataplaneUrlsEtcdKeyPrefix = process.env.BSKY_DATAPLANE_URLS_ETCD_KEY_PREFIX || undefined;
59
60
  const dataplaneHttpVersion = process.env.BSKY_DATAPLANE_HTTP_VERSION || '2';
@@ -194,6 +195,7 @@ export class ServerConfig {
194
195
  topicsUrl,
195
196
  topicsApiKey,
196
197
  irisUrl,
198
+ irisFeedUris,
197
199
  didPlcUrl,
198
200
  labelsFromIssuerDids,
199
201
  handleResolveNameservers,
@@ -349,6 +351,9 @@ export class ServerConfig {
349
351
  get irisUrl() {
350
352
  return this.cfg.irisUrl;
351
353
  }
354
+ get irisFeedUris() {
355
+ return this.cfg.irisFeedUris;
356
+ }
352
357
  get cdnUrl() {
353
358
  return this.cfg.cdnUrl;
354
359
  }
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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","sourcesContent":["import assert from 'node:assert'\nimport { noUndefinedVals } from '@atproto/common'\nimport { type DidString, isDidString } from '@atproto/lex'\nimport { subLogger as log } from './logger.js'\n\ntype LiveNowConfig = {\n did: DidString\n domains: string[]\n}[]\n\nexport interface KwsConfig {\n apiKey: string\n apiOrigin: string\n authOrigin: string\n clientId: string\n redirectUrl: string\n userAgent: string\n /**\n * V1 secret used to validate `adult-verifieid` redirects\n */\n verificationSecret: string\n /**\n * V1 secret used to validate `adult-verified` webhooks\n */\n webhookSecret: string\n /**\n * V2 secret used to validate `age-verified` webhooks\n */\n ageVerifiedWebhookSecret: string\n /**\n * V2 secret used to validate `age-verified` redirects\n */\n ageVerifiedRedirectSecret: string\n}\n\nexport interface ServerConfigValues {\n // service\n version?: string\n debugMode?: boolean\n port?: number\n publicUrl?: string\n serverDid: DidString\n alternateAudienceDids: DidString[]\n entrywayJwtPublicKeyHex?: string\n liveNowConfig?: LiveNowConfig\n // external services\n etcdHosts: string[]\n dataplaneUrls: string[]\n dataplaneUrlsEtcdKeyPrefix?: string\n dataplaneHttpVersion?: '1.1' | '2'\n dataplaneIgnoreBadTls?: boolean\n bsyncUrl: string\n bsyncApiKey?: string\n bsyncHttpVersion?: '1.1' | '2'\n bsyncIgnoreBadTls?: boolean\n courierUrl?: string\n courierApiKey?: string\n courierHttpVersion?: '1.1' | '2'\n courierIgnoreBadTls?: boolean\n rolodexUrl?: string\n rolodexApiKey?: string\n rolodexHttpVersion?: '1.1' | '2'\n rolodexIgnoreBadTls?: boolean\n searchUrl?: string\n searchTagsHide: Set<string>\n searchTagsHideAll: Set<string>\n suggestionsUrl?: string\n suggestionsApiKey?: string\n topicsUrl?: string\n topicsApiKey?: string\n irisUrl?: string\n cdnUrl?: string\n videoPlaylistUrlPattern?: string\n videoThumbnailUrlPattern?: string\n blobRateLimitBypassKey?: string\n blobRateLimitBypassHostname?: string\n // identity\n didPlcUrl: string\n handleResolveNameservers?: string[]\n // moderation and administration\n modServiceDid: DidString\n adminPasswords: string[]\n labelsFromIssuerDids?: DidString[]\n indexedAtEpoch?: Date\n // misc/dev\n blobCacheLocation?: string\n eventProxyTrackingEndpoint?: string\n growthBookApiHost?: string\n growthBookClientKey?: string\n // threads\n bigThreadUris: Set<string>\n bigThreadDepth?: number\n maxThreadDepth?: number\n maxThreadParents: number\n threadTagsHide: Set<string>\n threadTagsBumpDown: Set<string>\n visibilityTagHide: string\n visibilityTagRankPrefix: string\n // notifications\n notificationsDelayMs?: number\n // client config\n clientCheckEmailConfirmed?: boolean\n topicsEnabled?: boolean\n // http proxy agent\n disableSsrfProtection?: boolean\n proxyAllowHTTP2?: boolean\n proxyHeadersTimeout?: number\n proxyBodyTimeout?: number\n proxyMaxResponseSize?: number\n proxyMaxRetries?: number\n proxyPreferCompressed?: boolean\n kws?: KwsConfig\n debugFieldAllowedDids: Set<string>\n draftsLimit: number\n searchV2OverrideHeader?: string\n}\n\nexport class ServerConfig {\n private assignedPort?: number\n constructor(private cfg: ServerConfigValues) {}\n\n static readEnv(overrides?: Partial<ServerConfigValues>) {\n const version = process.env.BSKY_VERSION || undefined\n const debugMode =\n // Because security related features are disabled in development mode, this requires explicit opt-in.\n process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test'\n const publicUrl = process.env.BSKY_PUBLIC_URL || undefined\n const serverDid = process.env.BSKY_SERVER_DID || 'did:example:test'\n assert(isDidString(serverDid))\n const envPort = parseInt(process.env.BSKY_PORT || '', 10)\n const port = isNaN(envPort) ? 2584 : envPort\n const didPlcUrl = process.env.BSKY_DID_PLC_URL || 'http://localhost:2582'\n const alternateAudienceDids = envList(process.env.BSKY_ALT_AUDIENCE_DIDS)\n assert(alternateAudienceDids.every(isDidString))\n const entrywayJwtPublicKeyHex =\n process.env.BSKY_ENTRYWAY_JWT_PUBLIC_KEY_HEX || undefined\n let liveNowConfig: LiveNowConfig | undefined\n if (process.env.BSKY_LIVE_NOW_CONFIG) {\n try {\n const parsed = JSON.parse(process.env.BSKY_LIVE_NOW_CONFIG)\n if (isLiveNowConfig(parsed)) {\n liveNowConfig = parsed\n } else {\n throw new Error('Live Now config failed format validation')\n }\n } catch (err) {\n log.error({ err }, 'Invalid BSKY_LIVE_NOW_CONFIG')\n }\n }\n const handleResolveNameservers = envList(\n process.env.BSKY_HANDLE_RESOLVE_NAMESERVERS,\n )\n const cdnUrl = process.env.BSKY_CDN_URL || process.env.BSKY_IMG_URI_ENDPOINT\n // Values 0 through 16\n const etcdHosts =\n overrides?.etcdHosts ?? envList(process.env.BSKY_ETCD_HOSTS)\n // e.g. https://video.invalid/watch/%s/%s/playlist.m3u8\n const videoPlaylistUrlPattern = process.env.BSKY_VIDEO_PLAYLIST_URL_PATTERN\n // e.g. https://video.invalid/watch/%s/%s/thumbnail.jpg\n const videoThumbnailUrlPattern =\n process.env.BSKY_VIDEO_THUMBNAIL_URL_PATTERN\n const blobCacheLocation = process.env.BSKY_BLOB_CACHE_LOC\n const searchUrl =\n process.env.BSKY_SEARCH_URL ||\n process.env.BSKY_SEARCH_ENDPOINT ||\n undefined\n const searchTagsHide = new Set(envList(process.env.BSKY_SEARCH_TAGS_HIDE))\n const searchTagsHideAll = new Set(\n envList(process.env.BSKY_SEARCH_TAGS_HIDE_ALL),\n )\n const suggestionsUrl = process.env.BSKY_SUGGESTIONS_URL || undefined\n const suggestionsApiKey = process.env.BSKY_SUGGESTIONS_API_KEY || undefined\n const topicsUrl = process.env.BSKY_TOPICS_URL || undefined\n const topicsApiKey = process.env.BSKY_TOPICS_API_KEY\n const irisUrl = process.env.BSKY_IRIS_URL || undefined\n const dataplaneUrls =\n overrides?.dataplaneUrls ?? envList(process.env.BSKY_DATAPLANE_URLS)\n const dataplaneUrlsEtcdKeyPrefix =\n process.env.BSKY_DATAPLANE_URLS_ETCD_KEY_PREFIX || undefined\n const dataplaneHttpVersion = process.env.BSKY_DATAPLANE_HTTP_VERSION || '2'\n const dataplaneIgnoreBadTls =\n process.env.BSKY_DATAPLANE_IGNORE_BAD_TLS === 'true'\n assert(\n !dataplaneUrlsEtcdKeyPrefix || etcdHosts.length,\n 'etcd prefix for dataplane urls may only be configured when there are etcd hosts',\n )\n assert(\n dataplaneUrls.length || dataplaneUrlsEtcdKeyPrefix,\n 'dataplane urls are not configured directly nor with etcd',\n )\n assert(dataplaneHttpVersion === '1.1' || dataplaneHttpVersion === '2')\n const labelsFromIssuerDids = envList(\n process.env.BSKY_LABELS_FROM_ISSUER_DIDS,\n )\n assert(labelsFromIssuerDids.every(isDidString))\n const bsyncUrl = process.env.BSKY_BSYNC_URL || undefined\n assert(bsyncUrl)\n const bsyncApiKey = process.env.BSKY_BSYNC_API_KEY || undefined\n const bsyncHttpVersion = process.env.BSKY_BSYNC_HTTP_VERSION || '2'\n const bsyncIgnoreBadTls = process.env.BSKY_BSYNC_IGNORE_BAD_TLS === 'true'\n assert(bsyncHttpVersion === '1.1' || bsyncHttpVersion === '2')\n const courierUrl = process.env.BSKY_COURIER_URL || undefined\n const courierApiKey = process.env.BSKY_COURIER_API_KEY || undefined\n const courierHttpVersion = process.env.BSKY_COURIER_HTTP_VERSION || '2'\n const courierIgnoreBadTls =\n process.env.BSKY_COURIER_IGNORE_BAD_TLS === 'true'\n assert(courierHttpVersion === '1.1' || courierHttpVersion === '2')\n const rolodexUrl = process.env.BSKY_ROLODEX_URL || undefined\n const rolodexApiKey = process.env.BSKY_ROLODEX_API_KEY || undefined\n const rolodexHttpVersion = process.env.BSKY_ROLODEX_HTTP_VERSION || '2'\n const rolodexIgnoreBadTls =\n process.env.BSKY_ROLODEX_IGNORE_BAD_TLS === 'true'\n assert(rolodexHttpVersion === '1.1' || rolodexHttpVersion === '2')\n const blobRateLimitBypassKey =\n process.env.BSKY_BLOB_RATE_LIMIT_BYPASS_KEY || undefined\n // single domain would be e.g. \"mypds.com\", subdomains are supported with a leading dot e.g. \".mypds.com\"\n const blobRateLimitBypassHostname =\n process.env.BSKY_BLOB_RATE_LIMIT_BYPASS_HOSTNAME || undefined\n assert(\n !blobRateLimitBypassKey || blobRateLimitBypassHostname,\n 'must specify a hostname when using a blob rate limit bypass key',\n )\n const adminPasswords = envList(\n process.env.BSKY_ADMIN_PASSWORDS || process.env.BSKY_ADMIN_PASSWORD,\n )\n const modServiceDid = process.env.MOD_SERVICE_DID\n assert(modServiceDid != null && isDidString(modServiceDid))\n\n const eventProxyTrackingEndpoint =\n process.env.BSKY_EVENT_PROXY_TRACKING_ENDPOINT || undefined\n const growthBookApiHost = process.env.BSKY_GROWTHBOOK_API_HOST || undefined\n const growthBookClientKey =\n process.env.NODE_ENV === 'test'\n ? 'secret-key'\n : process.env.BSKY_GROWTHBOOK_CLIENT_KEY || undefined\n const clientCheckEmailConfirmed =\n process.env.BSKY_CLIENT_CHECK_EMAIL_CONFIRMED === 'true'\n const topicsEnabled = process.env.BSKY_TOPICS_ENABLED === 'true'\n const indexedAtEpoch = process.env.BSKY_INDEXED_AT_EPOCH\n ? new Date(process.env.BSKY_INDEXED_AT_EPOCH)\n : undefined\n assert(\n !indexedAtEpoch || !isNaN(indexedAtEpoch.getTime()),\n 'invalid BSKY_INDEXED_AT_EPOCH',\n )\n const bigThreadUris = new Set(envList(process.env.BSKY_BIG_THREAD_URIS))\n const bigThreadDepth = process.env.BSKY_BIG_THREAD_DEPTH\n ? parseInt(process.env.BSKY_BIG_THREAD_DEPTH || '', 10)\n : undefined\n const maxThreadDepth = process.env.BSKY_MAX_THREAD_DEPTH\n ? parseInt(process.env.BSKY_MAX_THREAD_DEPTH || '', 10)\n : undefined\n const maxThreadParents = process.env.BSKY_MAX_THREAD_PARENTS\n ? parseInt(process.env.BSKY_MAX_THREAD_PARENTS || '', 10)\n : 50\n const threadTagsHide = new Set(envList(process.env.BSKY_THREAD_TAGS_HIDE))\n const threadTagsBumpDown = new Set(\n envList(process.env.BSKY_THREAD_TAGS_BUMP_DOWN),\n )\n const visibilityTagHide = process.env.BSKY_VISIBILITY_TAG_HIDE || ''\n const visibilityTagRankPrefix =\n process.env.BSKY_VISIBILITY_TAG_RANK_PREFIX || ''\n\n const notificationsDelayMs = process.env.BSKY_NOTIFICATIONS_DELAY_MS\n ? parseInt(process.env.BSKY_NOTIFICATIONS_DELAY_MS || '', 10)\n : 0\n\n const disableSsrfProtection = process.env.BSKY_DISABLE_SSRF_PROTECTION\n ? process.env.BSKY_DISABLE_SSRF_PROTECTION === 'true'\n : debugMode\n\n const proxyAllowHTTP2 = process.env.BSKY_PROXY_ALLOW_HTTP2 === 'true'\n const proxyHeadersTimeout =\n parseInt(process.env.BSKY_PROXY_HEADERS_TIMEOUT || '', 10) || undefined\n const proxyBodyTimeout =\n parseInt(process.env.BSKY_PROXY_BODY_TIMEOUT || '', 10) || undefined\n const proxyMaxResponseSize =\n parseInt(process.env.BSKY_PROXY_MAX_RESPONSE_SIZE || '', 10) || undefined\n const proxyMaxRetries =\n parseInt(process.env.BSKY_PROXY_MAX_RETRIES || '', 10) || undefined\n const proxyPreferCompressed =\n process.env.BSKY_PROXY_PREFER_COMPRESSED === 'true'\n\n let kws: KwsConfig | undefined\n const kwsApiKey = process.env.BSKY_KWS_API_KEY\n const kwsApiOrigin = process.env.BSKY_KWS_API_ORIGIN\n const kwsAuthOrigin = process.env.BSKY_KWS_AUTH_ORIGIN\n const kwsClientId = process.env.BSKY_KWS_CLIENT_ID\n const kwsRedirectUrl = process.env.BSKY_KWS_REDIRECT_URL\n const kwsUserAgent = process.env.BSKY_KWS_USER_AGENT\n const kwsVerificationSecret = process.env.BSKY_KWS_VERIFICATION_SECRET\n const kwsWebhookSecret = process.env.BSKY_KWS_WEBHOOK_SECRET\n const kwsAgeVerifiedWebhookSecret =\n process.env.BSKY_KWS_AGE_VERIFIED_WEBHOOK_SECRET\n const kwsAgeVerifiedRedirectSecret =\n process.env.BSKY_KWS_AGE_VERIFIED_REDIRECT_SECRET\n if (\n kwsApiKey ||\n kwsApiOrigin ||\n kwsAuthOrigin ||\n kwsClientId ||\n kwsRedirectUrl ||\n kwsUserAgent ||\n kwsVerificationSecret ||\n kwsWebhookSecret ||\n kwsAgeVerifiedWebhookSecret ||\n kwsAgeVerifiedRedirectSecret\n ) {\n assert(\n kwsApiOrigin &&\n kwsAuthOrigin &&\n kwsClientId &&\n kwsRedirectUrl &&\n kwsUserAgent &&\n kwsVerificationSecret &&\n kwsWebhookSecret &&\n kwsApiKey &&\n kwsAgeVerifiedWebhookSecret &&\n kwsAgeVerifiedRedirectSecret,\n 'all KWS environment variables must be set if any are set',\n )\n kws = {\n apiKey: kwsApiKey,\n apiOrigin: kwsApiOrigin,\n authOrigin: kwsAuthOrigin,\n clientId: kwsClientId,\n redirectUrl: kwsRedirectUrl,\n userAgent: kwsUserAgent,\n verificationSecret: kwsVerificationSecret,\n webhookSecret: kwsWebhookSecret,\n ageVerifiedWebhookSecret: kwsAgeVerifiedWebhookSecret,\n ageVerifiedRedirectSecret: kwsAgeVerifiedRedirectSecret,\n }\n }\n\n const debugFieldAllowedDids = new Set(\n envList(process.env.BSKY_DEBUG_FIELD_ALLOWED_DIDS),\n )\n\n const draftsLimit = process.env.BSKY_DRAFTS_LIMIT\n ? parseInt(process.env.BSKY_DRAFTS_LIMIT || '', 10)\n : 500\n\n const searchV2OverrideHeader =\n process.env.BSKY_SEARCH_V2_OVERRIDE_HEADER || undefined\n\n return new ServerConfig({\n version,\n debugMode,\n port,\n publicUrl,\n serverDid,\n alternateAudienceDids,\n entrywayJwtPublicKeyHex,\n liveNowConfig,\n etcdHosts,\n dataplaneUrls,\n dataplaneUrlsEtcdKeyPrefix,\n dataplaneHttpVersion,\n dataplaneIgnoreBadTls,\n searchUrl,\n searchTagsHide,\n searchTagsHideAll,\n suggestionsUrl,\n suggestionsApiKey,\n topicsUrl,\n topicsApiKey,\n irisUrl,\n didPlcUrl,\n labelsFromIssuerDids,\n handleResolveNameservers,\n cdnUrl,\n videoPlaylistUrlPattern,\n videoThumbnailUrlPattern,\n blobCacheLocation,\n bsyncUrl,\n bsyncApiKey,\n bsyncHttpVersion,\n bsyncIgnoreBadTls,\n courierUrl,\n courierApiKey,\n courierHttpVersion,\n courierIgnoreBadTls,\n rolodexUrl,\n rolodexApiKey,\n rolodexHttpVersion,\n rolodexIgnoreBadTls,\n blobRateLimitBypassKey,\n blobRateLimitBypassHostname,\n adminPasswords,\n modServiceDid,\n eventProxyTrackingEndpoint,\n growthBookApiHost,\n growthBookClientKey,\n clientCheckEmailConfirmed,\n topicsEnabled,\n indexedAtEpoch,\n bigThreadUris,\n bigThreadDepth,\n maxThreadDepth,\n maxThreadParents,\n threadTagsHide,\n threadTagsBumpDown,\n visibilityTagHide,\n visibilityTagRankPrefix,\n notificationsDelayMs,\n disableSsrfProtection,\n proxyAllowHTTP2,\n proxyHeadersTimeout,\n proxyBodyTimeout,\n proxyMaxResponseSize,\n proxyMaxRetries,\n proxyPreferCompressed,\n kws,\n debugFieldAllowedDids,\n draftsLimit,\n searchV2OverrideHeader,\n ...noUndefinedVals(overrides ?? {}),\n })\n }\n\n assignPort(port: number) {\n assert(\n !this.cfg.port || this.cfg.port === port,\n 'Conflicting port in config',\n )\n this.assignedPort = port\n }\n\n get version() {\n return this.cfg.version\n }\n\n get debugMode() {\n return !!this.cfg.debugMode\n }\n\n get port() {\n return this.assignedPort || this.cfg.port\n }\n\n get publicUrl() {\n return this.cfg.publicUrl\n }\n\n get serverDid() {\n return this.cfg.serverDid\n }\n\n get alternateAudienceDids() {\n return this.cfg.alternateAudienceDids\n }\n\n get entrywayJwtPublicKeyHex() {\n return this.cfg.entrywayJwtPublicKeyHex\n }\n\n get liveNowConfig() {\n return this.cfg.liveNowConfig\n }\n\n get etcdHosts() {\n return this.cfg.etcdHosts\n }\n\n get dataplaneUrlsEtcdKeyPrefix() {\n return this.cfg.dataplaneUrlsEtcdKeyPrefix\n }\n\n get dataplaneUrls() {\n return this.cfg.dataplaneUrls\n }\n\n get dataplaneHttpVersion() {\n return this.cfg.dataplaneHttpVersion\n }\n\n get dataplaneIgnoreBadTls() {\n return this.cfg.dataplaneIgnoreBadTls\n }\n\n get bsyncUrl() {\n return this.cfg.bsyncUrl\n }\n\n get bsyncApiKey() {\n return this.cfg.bsyncApiKey\n }\n\n get bsyncHttpVersion() {\n return this.cfg.bsyncHttpVersion\n }\n\n get bsyncIgnoreBadTls() {\n return this.cfg.bsyncIgnoreBadTls\n }\n\n get courierUrl() {\n return this.cfg.courierUrl\n }\n\n get courierApiKey() {\n return this.cfg.courierApiKey\n }\n\n get courierHttpVersion() {\n return this.cfg.courierHttpVersion\n }\n\n get courierIgnoreBadTls() {\n return this.cfg.courierIgnoreBadTls\n }\n\n get rolodexUrl() {\n return this.cfg.rolodexUrl\n }\n get rolodexApiKey() {\n return this.cfg.rolodexApiKey\n }\n get rolodexHttpVersion() {\n return this.cfg.rolodexHttpVersion\n }\n get rolodexIgnoreBadTls() {\n return this.cfg.rolodexIgnoreBadTls\n }\n\n get searchUrl() {\n return this.cfg.searchUrl\n }\n\n get searchTagsHide() {\n return this.cfg.searchTagsHide\n }\n\n get searchTagsHideAll() {\n return this.cfg.searchTagsHideAll\n }\n\n get suggestionsUrl() {\n return this.cfg.suggestionsUrl\n }\n\n get suggestionsApiKey() {\n return this.cfg.suggestionsApiKey\n }\n\n get topicsUrl() {\n return this.cfg.topicsUrl\n }\n\n get topicsApiKey() {\n return this.cfg.topicsApiKey\n }\n\n get irisUrl() {\n return this.cfg.irisUrl\n }\n\n get cdnUrl() {\n return this.cfg.cdnUrl\n }\n\n get videoPlaylistUrlPattern() {\n return this.cfg.videoPlaylistUrlPattern\n }\n\n get videoThumbnailUrlPattern() {\n return this.cfg.videoThumbnailUrlPattern\n }\n\n get blobRateLimitBypassKey() {\n return this.cfg.blobRateLimitBypassKey\n }\n\n get blobRateLimitBypassHostname() {\n return this.cfg.blobRateLimitBypassHostname\n }\n\n get didPlcUrl() {\n return this.cfg.didPlcUrl\n }\n\n get handleResolveNameservers() {\n return this.cfg.handleResolveNameservers\n }\n\n get adminPasswords() {\n return this.cfg.adminPasswords\n }\n\n get modServiceDid() {\n return this.cfg.modServiceDid\n }\n\n get labelsFromIssuerDids() {\n return (this.cfg.labelsFromIssuerDids ?? []) as DidString[]\n }\n\n get blobCacheLocation() {\n return this.cfg.blobCacheLocation\n }\n\n get eventProxyTrackingEndpoint() {\n return this.cfg.eventProxyTrackingEndpoint\n }\n\n get growthBookApiHost() {\n return this.cfg.growthBookApiHost\n }\n\n get growthBookClientKey() {\n return this.cfg.growthBookClientKey\n }\n\n get clientCheckEmailConfirmed() {\n return this.cfg.clientCheckEmailConfirmed\n }\n\n get topicsEnabled() {\n return this.cfg.topicsEnabled\n }\n\n get indexedAtEpoch() {\n return this.cfg.indexedAtEpoch\n }\n\n get bigThreadUris() {\n return this.cfg.bigThreadUris\n }\n\n get bigThreadDepth() {\n return this.cfg.bigThreadDepth\n }\n\n get maxThreadDepth() {\n return this.cfg.maxThreadDepth\n }\n\n get maxThreadParents() {\n return this.cfg.maxThreadParents\n }\n\n get threadTagsHide() {\n return this.cfg.threadTagsHide\n }\n\n get threadTagsBumpDown() {\n return this.cfg.threadTagsBumpDown\n }\n\n get visibilityTagHide() {\n return this.cfg.visibilityTagHide\n }\n\n get visibilityTagRankPrefix() {\n return this.cfg.visibilityTagRankPrefix\n }\n\n get notificationsDelayMs() {\n return this.cfg.notificationsDelayMs ?? 0\n }\n\n get disableSsrfProtection(): boolean {\n return this.cfg.disableSsrfProtection ?? false\n }\n\n get proxyAllowHTTP2(): boolean {\n return this.cfg.proxyAllowHTTP2 ?? false\n }\n\n get proxyHeadersTimeout(): number {\n return this.cfg.proxyHeadersTimeout ?? 30e3\n }\n\n get proxyBodyTimeout(): number {\n return this.cfg.proxyBodyTimeout ?? 30e3\n }\n\n get proxyMaxResponseSize(): number {\n return this.cfg.proxyMaxResponseSize ?? 10 * 1024 * 1024 // 10mb\n }\n\n get proxyMaxRetries(): number {\n return this.cfg.proxyMaxRetries ?? 3\n }\n\n get proxyPreferCompressed(): boolean {\n return this.cfg.proxyPreferCompressed ?? true\n }\n\n get kws() {\n return this.cfg.kws\n }\n\n get debugFieldAllowedDids() {\n return this.cfg.debugFieldAllowedDids\n }\n\n get draftsLimit() {\n return this.cfg.draftsLimit\n }\n\n get searchV2OverrideHeader() {\n return this.cfg.searchV2OverrideHeader\n }\n}\n\nfunction envList(str: string | undefined): string[] {\n if (str === undefined || str.length === 0) return []\n return str.split(',')\n}\n\nfunction isLiveNowConfig(data: any): data is LiveNowConfig {\n return (\n Array.isArray(data) &&\n data.every(\n (item) =>\n typeof item === 'object' &&\n item !== null &&\n typeof item.did === 'string' &&\n isDidString(item.did) &&\n Array.isArray(item.domains) &&\n item.domains.every((domain: any) => typeof domain === 'string'),\n )\n )\n}\n"]}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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","sourcesContent":["import assert from 'node:assert'\nimport { noUndefinedVals } from '@atproto/common'\nimport { type DidString, isDidString } from '@atproto/lex'\nimport { subLogger as log } from './logger.js'\n\ntype LiveNowConfig = {\n did: DidString\n domains: string[]\n}[]\n\nexport interface KwsConfig {\n apiKey: string\n apiOrigin: string\n authOrigin: string\n clientId: string\n redirectUrl: string\n userAgent: string\n /**\n * V1 secret used to validate `adult-verifieid` redirects\n */\n verificationSecret: string\n /**\n * V1 secret used to validate `adult-verified` webhooks\n */\n webhookSecret: string\n /**\n * V2 secret used to validate `age-verified` webhooks\n */\n ageVerifiedWebhookSecret: string\n /**\n * V2 secret used to validate `age-verified` redirects\n */\n ageVerifiedRedirectSecret: string\n}\n\nexport interface ServerConfigValues {\n // service\n version?: string\n debugMode?: boolean\n port?: number\n publicUrl?: string\n serverDid: DidString\n alternateAudienceDids: DidString[]\n entrywayJwtPublicKeyHex?: string\n liveNowConfig?: LiveNowConfig\n // external services\n etcdHosts: string[]\n dataplaneUrls: string[]\n dataplaneUrlsEtcdKeyPrefix?: string\n dataplaneHttpVersion?: '1.1' | '2'\n dataplaneIgnoreBadTls?: boolean\n bsyncUrl: string\n bsyncApiKey?: string\n bsyncHttpVersion?: '1.1' | '2'\n bsyncIgnoreBadTls?: boolean\n courierUrl?: string\n courierApiKey?: string\n courierHttpVersion?: '1.1' | '2'\n courierIgnoreBadTls?: boolean\n rolodexUrl?: string\n rolodexApiKey?: string\n rolodexHttpVersion?: '1.1' | '2'\n rolodexIgnoreBadTls?: boolean\n searchUrl?: string\n searchTagsHide: Set<string>\n searchTagsHideAll: Set<string>\n suggestionsUrl?: string\n suggestionsApiKey?: string\n topicsUrl?: string\n topicsApiKey?: string\n irisUrl?: string\n irisFeedUris?: Set<string> // `iris:feed:enable` gate to serve via iris instead of seeemore\n cdnUrl?: string\n videoPlaylistUrlPattern?: string\n videoThumbnailUrlPattern?: string\n blobRateLimitBypassKey?: string\n blobRateLimitBypassHostname?: string\n // identity\n didPlcUrl: string\n handleResolveNameservers?: string[]\n // moderation and administration\n modServiceDid: DidString\n adminPasswords: string[]\n labelsFromIssuerDids?: DidString[]\n indexedAtEpoch?: Date\n // misc/dev\n blobCacheLocation?: string\n eventProxyTrackingEndpoint?: string\n growthBookApiHost?: string\n growthBookClientKey?: string\n // threads\n bigThreadUris: Set<string>\n bigThreadDepth?: number\n maxThreadDepth?: number\n maxThreadParents: number\n threadTagsHide: Set<string>\n threadTagsBumpDown: Set<string>\n visibilityTagHide: string\n visibilityTagRankPrefix: string\n // notifications\n notificationsDelayMs?: number\n // client config\n clientCheckEmailConfirmed?: boolean\n topicsEnabled?: boolean\n // http proxy agent\n disableSsrfProtection?: boolean\n proxyAllowHTTP2?: boolean\n proxyHeadersTimeout?: number\n proxyBodyTimeout?: number\n proxyMaxResponseSize?: number\n proxyMaxRetries?: number\n proxyPreferCompressed?: boolean\n kws?: KwsConfig\n debugFieldAllowedDids: Set<string>\n draftsLimit: number\n searchV2OverrideHeader?: string\n}\n\nexport class ServerConfig {\n private assignedPort?: number\n constructor(private cfg: ServerConfigValues) {}\n\n static readEnv(overrides?: Partial<ServerConfigValues>) {\n const version = process.env.BSKY_VERSION || undefined\n const debugMode =\n // Because security related features are disabled in development mode, this requires explicit opt-in.\n process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test'\n const publicUrl = process.env.BSKY_PUBLIC_URL || undefined\n const serverDid = process.env.BSKY_SERVER_DID || 'did:example:test'\n assert(isDidString(serverDid))\n const envPort = parseInt(process.env.BSKY_PORT || '', 10)\n const port = isNaN(envPort) ? 2584 : envPort\n const didPlcUrl = process.env.BSKY_DID_PLC_URL || 'http://localhost:2582'\n const alternateAudienceDids = envList(process.env.BSKY_ALT_AUDIENCE_DIDS)\n assert(alternateAudienceDids.every(isDidString))\n const entrywayJwtPublicKeyHex =\n process.env.BSKY_ENTRYWAY_JWT_PUBLIC_KEY_HEX || undefined\n let liveNowConfig: LiveNowConfig | undefined\n if (process.env.BSKY_LIVE_NOW_CONFIG) {\n try {\n const parsed = JSON.parse(process.env.BSKY_LIVE_NOW_CONFIG)\n if (isLiveNowConfig(parsed)) {\n liveNowConfig = parsed\n } else {\n throw new Error('Live Now config failed format validation')\n }\n } catch (err) {\n log.error({ err }, 'Invalid BSKY_LIVE_NOW_CONFIG')\n }\n }\n const handleResolveNameservers = envList(\n process.env.BSKY_HANDLE_RESOLVE_NAMESERVERS,\n )\n const cdnUrl = process.env.BSKY_CDN_URL || process.env.BSKY_IMG_URI_ENDPOINT\n // Values 0 through 16\n const etcdHosts =\n overrides?.etcdHosts ?? envList(process.env.BSKY_ETCD_HOSTS)\n // e.g. https://video.invalid/watch/%s/%s/playlist.m3u8\n const videoPlaylistUrlPattern = process.env.BSKY_VIDEO_PLAYLIST_URL_PATTERN\n // e.g. https://video.invalid/watch/%s/%s/thumbnail.jpg\n const videoThumbnailUrlPattern =\n process.env.BSKY_VIDEO_THUMBNAIL_URL_PATTERN\n const blobCacheLocation = process.env.BSKY_BLOB_CACHE_LOC\n const searchUrl =\n process.env.BSKY_SEARCH_URL ||\n process.env.BSKY_SEARCH_ENDPOINT ||\n undefined\n const searchTagsHide = new Set(envList(process.env.BSKY_SEARCH_TAGS_HIDE))\n const searchTagsHideAll = new Set(\n envList(process.env.BSKY_SEARCH_TAGS_HIDE_ALL),\n )\n const suggestionsUrl = process.env.BSKY_SUGGESTIONS_URL || undefined\n const suggestionsApiKey = process.env.BSKY_SUGGESTIONS_API_KEY || undefined\n const topicsUrl = process.env.BSKY_TOPICS_URL || undefined\n const topicsApiKey = process.env.BSKY_TOPICS_API_KEY\n const irisUrl = process.env.BSKY_IRIS_URL || undefined\n const irisFeedUris = new Set(envList(process.env.BSKY_IRIS_FEED_URIS))\n const dataplaneUrls =\n overrides?.dataplaneUrls ?? envList(process.env.BSKY_DATAPLANE_URLS)\n const dataplaneUrlsEtcdKeyPrefix =\n process.env.BSKY_DATAPLANE_URLS_ETCD_KEY_PREFIX || undefined\n const dataplaneHttpVersion = process.env.BSKY_DATAPLANE_HTTP_VERSION || '2'\n const dataplaneIgnoreBadTls =\n process.env.BSKY_DATAPLANE_IGNORE_BAD_TLS === 'true'\n assert(\n !dataplaneUrlsEtcdKeyPrefix || etcdHosts.length,\n 'etcd prefix for dataplane urls may only be configured when there are etcd hosts',\n )\n assert(\n dataplaneUrls.length || dataplaneUrlsEtcdKeyPrefix,\n 'dataplane urls are not configured directly nor with etcd',\n )\n assert(dataplaneHttpVersion === '1.1' || dataplaneHttpVersion === '2')\n const labelsFromIssuerDids = envList(\n process.env.BSKY_LABELS_FROM_ISSUER_DIDS,\n )\n assert(labelsFromIssuerDids.every(isDidString))\n const bsyncUrl = process.env.BSKY_BSYNC_URL || undefined\n assert(bsyncUrl)\n const bsyncApiKey = process.env.BSKY_BSYNC_API_KEY || undefined\n const bsyncHttpVersion = process.env.BSKY_BSYNC_HTTP_VERSION || '2'\n const bsyncIgnoreBadTls = process.env.BSKY_BSYNC_IGNORE_BAD_TLS === 'true'\n assert(bsyncHttpVersion === '1.1' || bsyncHttpVersion === '2')\n const courierUrl = process.env.BSKY_COURIER_URL || undefined\n const courierApiKey = process.env.BSKY_COURIER_API_KEY || undefined\n const courierHttpVersion = process.env.BSKY_COURIER_HTTP_VERSION || '2'\n const courierIgnoreBadTls =\n process.env.BSKY_COURIER_IGNORE_BAD_TLS === 'true'\n assert(courierHttpVersion === '1.1' || courierHttpVersion === '2')\n const rolodexUrl = process.env.BSKY_ROLODEX_URL || undefined\n const rolodexApiKey = process.env.BSKY_ROLODEX_API_KEY || undefined\n const rolodexHttpVersion = process.env.BSKY_ROLODEX_HTTP_VERSION || '2'\n const rolodexIgnoreBadTls =\n process.env.BSKY_ROLODEX_IGNORE_BAD_TLS === 'true'\n assert(rolodexHttpVersion === '1.1' || rolodexHttpVersion === '2')\n const blobRateLimitBypassKey =\n process.env.BSKY_BLOB_RATE_LIMIT_BYPASS_KEY || undefined\n // single domain would be e.g. \"mypds.com\", subdomains are supported with a leading dot e.g. \".mypds.com\"\n const blobRateLimitBypassHostname =\n process.env.BSKY_BLOB_RATE_LIMIT_BYPASS_HOSTNAME || undefined\n assert(\n !blobRateLimitBypassKey || blobRateLimitBypassHostname,\n 'must specify a hostname when using a blob rate limit bypass key',\n )\n const adminPasswords = envList(\n process.env.BSKY_ADMIN_PASSWORDS || process.env.BSKY_ADMIN_PASSWORD,\n )\n const modServiceDid = process.env.MOD_SERVICE_DID\n assert(modServiceDid != null && isDidString(modServiceDid))\n\n const eventProxyTrackingEndpoint =\n process.env.BSKY_EVENT_PROXY_TRACKING_ENDPOINT || undefined\n const growthBookApiHost = process.env.BSKY_GROWTHBOOK_API_HOST || undefined\n const growthBookClientKey =\n process.env.NODE_ENV === 'test'\n ? 'secret-key'\n : process.env.BSKY_GROWTHBOOK_CLIENT_KEY || undefined\n const clientCheckEmailConfirmed =\n process.env.BSKY_CLIENT_CHECK_EMAIL_CONFIRMED === 'true'\n const topicsEnabled = process.env.BSKY_TOPICS_ENABLED === 'true'\n const indexedAtEpoch = process.env.BSKY_INDEXED_AT_EPOCH\n ? new Date(process.env.BSKY_INDEXED_AT_EPOCH)\n : undefined\n assert(\n !indexedAtEpoch || !isNaN(indexedAtEpoch.getTime()),\n 'invalid BSKY_INDEXED_AT_EPOCH',\n )\n const bigThreadUris = new Set(envList(process.env.BSKY_BIG_THREAD_URIS))\n const bigThreadDepth = process.env.BSKY_BIG_THREAD_DEPTH\n ? parseInt(process.env.BSKY_BIG_THREAD_DEPTH || '', 10)\n : undefined\n const maxThreadDepth = process.env.BSKY_MAX_THREAD_DEPTH\n ? parseInt(process.env.BSKY_MAX_THREAD_DEPTH || '', 10)\n : undefined\n const maxThreadParents = process.env.BSKY_MAX_THREAD_PARENTS\n ? parseInt(process.env.BSKY_MAX_THREAD_PARENTS || '', 10)\n : 50\n const threadTagsHide = new Set(envList(process.env.BSKY_THREAD_TAGS_HIDE))\n const threadTagsBumpDown = new Set(\n envList(process.env.BSKY_THREAD_TAGS_BUMP_DOWN),\n )\n const visibilityTagHide = process.env.BSKY_VISIBILITY_TAG_HIDE || ''\n const visibilityTagRankPrefix =\n process.env.BSKY_VISIBILITY_TAG_RANK_PREFIX || ''\n\n const notificationsDelayMs = process.env.BSKY_NOTIFICATIONS_DELAY_MS\n ? parseInt(process.env.BSKY_NOTIFICATIONS_DELAY_MS || '', 10)\n : 0\n\n const disableSsrfProtection = process.env.BSKY_DISABLE_SSRF_PROTECTION\n ? process.env.BSKY_DISABLE_SSRF_PROTECTION === 'true'\n : debugMode\n\n const proxyAllowHTTP2 = process.env.BSKY_PROXY_ALLOW_HTTP2 === 'true'\n const proxyHeadersTimeout =\n parseInt(process.env.BSKY_PROXY_HEADERS_TIMEOUT || '', 10) || undefined\n const proxyBodyTimeout =\n parseInt(process.env.BSKY_PROXY_BODY_TIMEOUT || '', 10) || undefined\n const proxyMaxResponseSize =\n parseInt(process.env.BSKY_PROXY_MAX_RESPONSE_SIZE || '', 10) || undefined\n const proxyMaxRetries =\n parseInt(process.env.BSKY_PROXY_MAX_RETRIES || '', 10) || undefined\n const proxyPreferCompressed =\n process.env.BSKY_PROXY_PREFER_COMPRESSED === 'true'\n\n let kws: KwsConfig | undefined\n const kwsApiKey = process.env.BSKY_KWS_API_KEY\n const kwsApiOrigin = process.env.BSKY_KWS_API_ORIGIN\n const kwsAuthOrigin = process.env.BSKY_KWS_AUTH_ORIGIN\n const kwsClientId = process.env.BSKY_KWS_CLIENT_ID\n const kwsRedirectUrl = process.env.BSKY_KWS_REDIRECT_URL\n const kwsUserAgent = process.env.BSKY_KWS_USER_AGENT\n const kwsVerificationSecret = process.env.BSKY_KWS_VERIFICATION_SECRET\n const kwsWebhookSecret = process.env.BSKY_KWS_WEBHOOK_SECRET\n const kwsAgeVerifiedWebhookSecret =\n process.env.BSKY_KWS_AGE_VERIFIED_WEBHOOK_SECRET\n const kwsAgeVerifiedRedirectSecret =\n process.env.BSKY_KWS_AGE_VERIFIED_REDIRECT_SECRET\n if (\n kwsApiKey ||\n kwsApiOrigin ||\n kwsAuthOrigin ||\n kwsClientId ||\n kwsRedirectUrl ||\n kwsUserAgent ||\n kwsVerificationSecret ||\n kwsWebhookSecret ||\n kwsAgeVerifiedWebhookSecret ||\n kwsAgeVerifiedRedirectSecret\n ) {\n assert(\n kwsApiOrigin &&\n kwsAuthOrigin &&\n kwsClientId &&\n kwsRedirectUrl &&\n kwsUserAgent &&\n kwsVerificationSecret &&\n kwsWebhookSecret &&\n kwsApiKey &&\n kwsAgeVerifiedWebhookSecret &&\n kwsAgeVerifiedRedirectSecret,\n 'all KWS environment variables must be set if any are set',\n )\n kws = {\n apiKey: kwsApiKey,\n apiOrigin: kwsApiOrigin,\n authOrigin: kwsAuthOrigin,\n clientId: kwsClientId,\n redirectUrl: kwsRedirectUrl,\n userAgent: kwsUserAgent,\n verificationSecret: kwsVerificationSecret,\n webhookSecret: kwsWebhookSecret,\n ageVerifiedWebhookSecret: kwsAgeVerifiedWebhookSecret,\n ageVerifiedRedirectSecret: kwsAgeVerifiedRedirectSecret,\n }\n }\n\n const debugFieldAllowedDids = new Set(\n envList(process.env.BSKY_DEBUG_FIELD_ALLOWED_DIDS),\n )\n\n const draftsLimit = process.env.BSKY_DRAFTS_LIMIT\n ? parseInt(process.env.BSKY_DRAFTS_LIMIT || '', 10)\n : 500\n\n const searchV2OverrideHeader =\n process.env.BSKY_SEARCH_V2_OVERRIDE_HEADER || undefined\n\n return new ServerConfig({\n version,\n debugMode,\n port,\n publicUrl,\n serverDid,\n alternateAudienceDids,\n entrywayJwtPublicKeyHex,\n liveNowConfig,\n etcdHosts,\n dataplaneUrls,\n dataplaneUrlsEtcdKeyPrefix,\n dataplaneHttpVersion,\n dataplaneIgnoreBadTls,\n searchUrl,\n searchTagsHide,\n searchTagsHideAll,\n suggestionsUrl,\n suggestionsApiKey,\n topicsUrl,\n topicsApiKey,\n irisUrl,\n irisFeedUris,\n didPlcUrl,\n labelsFromIssuerDids,\n handleResolveNameservers,\n cdnUrl,\n videoPlaylistUrlPattern,\n videoThumbnailUrlPattern,\n blobCacheLocation,\n bsyncUrl,\n bsyncApiKey,\n bsyncHttpVersion,\n bsyncIgnoreBadTls,\n courierUrl,\n courierApiKey,\n courierHttpVersion,\n courierIgnoreBadTls,\n rolodexUrl,\n rolodexApiKey,\n rolodexHttpVersion,\n rolodexIgnoreBadTls,\n blobRateLimitBypassKey,\n blobRateLimitBypassHostname,\n adminPasswords,\n modServiceDid,\n eventProxyTrackingEndpoint,\n growthBookApiHost,\n growthBookClientKey,\n clientCheckEmailConfirmed,\n topicsEnabled,\n indexedAtEpoch,\n bigThreadUris,\n bigThreadDepth,\n maxThreadDepth,\n maxThreadParents,\n threadTagsHide,\n threadTagsBumpDown,\n visibilityTagHide,\n visibilityTagRankPrefix,\n notificationsDelayMs,\n disableSsrfProtection,\n proxyAllowHTTP2,\n proxyHeadersTimeout,\n proxyBodyTimeout,\n proxyMaxResponseSize,\n proxyMaxRetries,\n proxyPreferCompressed,\n kws,\n debugFieldAllowedDids,\n draftsLimit,\n searchV2OverrideHeader,\n ...noUndefinedVals(overrides ?? {}),\n })\n }\n\n assignPort(port: number) {\n assert(\n !this.cfg.port || this.cfg.port === port,\n 'Conflicting port in config',\n )\n this.assignedPort = port\n }\n\n get version() {\n return this.cfg.version\n }\n\n get debugMode() {\n return !!this.cfg.debugMode\n }\n\n get port() {\n return this.assignedPort || this.cfg.port\n }\n\n get publicUrl() {\n return this.cfg.publicUrl\n }\n\n get serverDid() {\n return this.cfg.serverDid\n }\n\n get alternateAudienceDids() {\n return this.cfg.alternateAudienceDids\n }\n\n get entrywayJwtPublicKeyHex() {\n return this.cfg.entrywayJwtPublicKeyHex\n }\n\n get liveNowConfig() {\n return this.cfg.liveNowConfig\n }\n\n get etcdHosts() {\n return this.cfg.etcdHosts\n }\n\n get dataplaneUrlsEtcdKeyPrefix() {\n return this.cfg.dataplaneUrlsEtcdKeyPrefix\n }\n\n get dataplaneUrls() {\n return this.cfg.dataplaneUrls\n }\n\n get dataplaneHttpVersion() {\n return this.cfg.dataplaneHttpVersion\n }\n\n get dataplaneIgnoreBadTls() {\n return this.cfg.dataplaneIgnoreBadTls\n }\n\n get bsyncUrl() {\n return this.cfg.bsyncUrl\n }\n\n get bsyncApiKey() {\n return this.cfg.bsyncApiKey\n }\n\n get bsyncHttpVersion() {\n return this.cfg.bsyncHttpVersion\n }\n\n get bsyncIgnoreBadTls() {\n return this.cfg.bsyncIgnoreBadTls\n }\n\n get courierUrl() {\n return this.cfg.courierUrl\n }\n\n get courierApiKey() {\n return this.cfg.courierApiKey\n }\n\n get courierHttpVersion() {\n return this.cfg.courierHttpVersion\n }\n\n get courierIgnoreBadTls() {\n return this.cfg.courierIgnoreBadTls\n }\n\n get rolodexUrl() {\n return this.cfg.rolodexUrl\n }\n get rolodexApiKey() {\n return this.cfg.rolodexApiKey\n }\n get rolodexHttpVersion() {\n return this.cfg.rolodexHttpVersion\n }\n get rolodexIgnoreBadTls() {\n return this.cfg.rolodexIgnoreBadTls\n }\n\n get searchUrl() {\n return this.cfg.searchUrl\n }\n\n get searchTagsHide() {\n return this.cfg.searchTagsHide\n }\n\n get searchTagsHideAll() {\n return this.cfg.searchTagsHideAll\n }\n\n get suggestionsUrl() {\n return this.cfg.suggestionsUrl\n }\n\n get suggestionsApiKey() {\n return this.cfg.suggestionsApiKey\n }\n\n get topicsUrl() {\n return this.cfg.topicsUrl\n }\n\n get topicsApiKey() {\n return this.cfg.topicsApiKey\n }\n\n get irisUrl() {\n return this.cfg.irisUrl\n }\n\n get irisFeedUris() {\n return this.cfg.irisFeedUris\n }\n\n get cdnUrl() {\n return this.cfg.cdnUrl\n }\n\n get videoPlaylistUrlPattern() {\n return this.cfg.videoPlaylistUrlPattern\n }\n\n get videoThumbnailUrlPattern() {\n return this.cfg.videoThumbnailUrlPattern\n }\n\n get blobRateLimitBypassKey() {\n return this.cfg.blobRateLimitBypassKey\n }\n\n get blobRateLimitBypassHostname() {\n return this.cfg.blobRateLimitBypassHostname\n }\n\n get didPlcUrl() {\n return this.cfg.didPlcUrl\n }\n\n get handleResolveNameservers() {\n return this.cfg.handleResolveNameservers\n }\n\n get adminPasswords() {\n return this.cfg.adminPasswords\n }\n\n get modServiceDid() {\n return this.cfg.modServiceDid\n }\n\n get labelsFromIssuerDids() {\n return (this.cfg.labelsFromIssuerDids ?? []) as DidString[]\n }\n\n get blobCacheLocation() {\n return this.cfg.blobCacheLocation\n }\n\n get eventProxyTrackingEndpoint() {\n return this.cfg.eventProxyTrackingEndpoint\n }\n\n get growthBookApiHost() {\n return this.cfg.growthBookApiHost\n }\n\n get growthBookClientKey() {\n return this.cfg.growthBookClientKey\n }\n\n get clientCheckEmailConfirmed() {\n return this.cfg.clientCheckEmailConfirmed\n }\n\n get topicsEnabled() {\n return this.cfg.topicsEnabled\n }\n\n get indexedAtEpoch() {\n return this.cfg.indexedAtEpoch\n }\n\n get bigThreadUris() {\n return this.cfg.bigThreadUris\n }\n\n get bigThreadDepth() {\n return this.cfg.bigThreadDepth\n }\n\n get maxThreadDepth() {\n return this.cfg.maxThreadDepth\n }\n\n get maxThreadParents() {\n return this.cfg.maxThreadParents\n }\n\n get threadTagsHide() {\n return this.cfg.threadTagsHide\n }\n\n get threadTagsBumpDown() {\n return this.cfg.threadTagsBumpDown\n }\n\n get visibilityTagHide() {\n return this.cfg.visibilityTagHide\n }\n\n get visibilityTagRankPrefix() {\n return this.cfg.visibilityTagRankPrefix\n }\n\n get notificationsDelayMs() {\n return this.cfg.notificationsDelayMs ?? 0\n }\n\n get disableSsrfProtection(): boolean {\n return this.cfg.disableSsrfProtection ?? false\n }\n\n get proxyAllowHTTP2(): boolean {\n return this.cfg.proxyAllowHTTP2 ?? false\n }\n\n get proxyHeadersTimeout(): number {\n return this.cfg.proxyHeadersTimeout ?? 30e3\n }\n\n get proxyBodyTimeout(): number {\n return this.cfg.proxyBodyTimeout ?? 30e3\n }\n\n get proxyMaxResponseSize(): number {\n return this.cfg.proxyMaxResponseSize ?? 10 * 1024 * 1024 // 10mb\n }\n\n get proxyMaxRetries(): number {\n return this.cfg.proxyMaxRetries ?? 3\n }\n\n get proxyPreferCompressed(): boolean {\n return this.cfg.proxyPreferCompressed ?? true\n }\n\n get kws() {\n return this.cfg.kws\n }\n\n get debugFieldAllowedDids() {\n return this.cfg.debugFieldAllowedDids\n }\n\n get draftsLimit() {\n return this.cfg.draftsLimit\n }\n\n get searchV2OverrideHeader() {\n return this.cfg.searchV2OverrideHeader\n }\n}\n\nfunction envList(str: string | undefined): string[] {\n if (str === undefined || str.length === 0) return []\n return str.split(',')\n}\n\nfunction isLiveNowConfig(data: any): data is LiveNowConfig {\n return (\n Array.isArray(data) &&\n data.every(\n (item) =>\n typeof item === 'object' &&\n item !== null &&\n typeof item.did === 'string' &&\n isDidString(item.did) &&\n Array.isArray(item.domains) &&\n item.domains.every((domain: any) => typeof domain === 'string'),\n )\n )\n}\n"]}
@@ -30,6 +30,10 @@ export declare abstract class GenericKeyset<R, LR extends KeysetLabeledResult> {
30
30
  abstract labeledResultToCursor(labeled: LR): KeysetCursor;
31
31
  abstract cursorToLabeledResult(cursor: KeysetCursor): LR;
32
32
  packFromResult(results: R | R[]): string | undefined;
33
+ page<Result extends R>(results: Result[], limit: number): {
34
+ items: Result[];
35
+ cursor?: string;
36
+ };
33
37
  pack(labeled?: LR): string | undefined;
34
38
  unpack(cursorStr?: string): LR | undefined;
35
39
  packCursor(cursor?: KeysetCursor): string | undefined;
@@ -110,6 +114,10 @@ export declare abstract class GenericSingleKey<R, LR extends SingleKeyLabeledRes
110
114
  abstract labeledResultToCursor(labeled: LR): SingleKeyCursor;
111
115
  abstract cursorToLabeledResult(cursor: SingleKeyCursor): LR;
112
116
  packFromResult(results: R | R[]): string | undefined;
117
+ page<Result extends R>(results: Result[], limit: number): {
118
+ items: Result[];
119
+ cursor?: string;
120
+ };
113
121
  pack(labeled?: LR): string | undefined;
114
122
  unpack(cursorStr?: string): LR | undefined;
115
123
  packCursor(cursor?: SingleKeyCursor): string | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"pagination.d.ts","sourceRoot":"","sources":["../../../../src/data-plane/server/db/pagination.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"pagination.d.ts","sourceRoot":"","sources":["../../../../src/data-plane/server/db/pagination.ts"],"names":[],"mappings":"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"}
@@ -26,6 +26,15 @@ export class GenericKeyset {
26
26
  return;
27
27
  return this.pack(this.labelResult(result));
28
28
  }
29
+ page(results, limit) {
30
+ const items = results.slice(0, limit);
31
+ return {
32
+ items,
33
+ cursor: results.length > limit && items.length
34
+ ? this.packFromResult(items[items.length - 1])
35
+ : undefined,
36
+ };
37
+ }
29
38
  pack(labeled) {
30
39
  if (!labeled)
31
40
  return;
@@ -82,7 +91,7 @@ export class GenericKeyset {
82
91
  const { limit, cursor, direction = 'desc', tryIndex, nullsLast } = opts;
83
92
  const keysetSql = this.getSql(this.unpack(cursor), direction, tryIndex);
84
93
  return qb
85
- .$if(!!limit, (q) => q.limit(limit))
94
+ .$if(!!limit, (q) => q.limit(limit + 1))
86
95
  .$if(!nullsLast, (q) => q.orderBy(this.primary, direction).orderBy(this.secondary, direction))
87
96
  .$if(!!nullsLast, (q) => q
88
97
  .orderBy(direction === 'asc'
@@ -144,6 +153,15 @@ export class GenericSingleKey {
144
153
  return;
145
154
  return this.pack(this.labelResult(result));
146
155
  }
156
+ page(results, limit) {
157
+ const items = results.slice(0, limit);
158
+ return {
159
+ items,
160
+ cursor: results.length > limit && items.length
161
+ ? this.packFromResult(items[items.length - 1])
162
+ : undefined,
163
+ };
164
+ }
147
165
  pack(labeled) {
148
166
  if (!labeled)
149
167
  return;
@@ -185,7 +203,7 @@ export class GenericSingleKey {
185
203
  const { limit, cursor, direction = 'desc', nullsLast } = opts;
186
204
  const keySql = this.getSql(this.unpack(cursor), direction);
187
205
  return qb
188
- .$if(!!limit, (q) => q.limit(limit))
206
+ .$if(!!limit, (q) => q.limit(limit + 1))
189
207
  .$if(!nullsLast, (q) => q.orderBy(this.primary, direction))
190
208
  .$if(!!nullsLast, (q) => q.orderBy(direction === 'asc'
191
209
  ? sql `${this.primary} asc nulls last`
@@ -1 +1 @@
1
- {"version":3,"file":"pagination.js","sourceRoot":"","sources":["../../../../src/data-plane/server/db/pagination.ts"],"names":[],"mappings":"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","sourcesContent":["import { type SqlBool, sql } from 'kysely'\nimport { ensureValidRecordKey } from '@atproto/syntax'\nimport { InvalidRequestError } from '@atproto/xrpc-server'\nimport type { AnyQb, DbRef } from './util.js'\n\ntype KeysetCursor = { primary: string; secondary: string }\ntype KeysetLabeledResult = {\n primary: string | number\n secondary: string | number\n}\n\n/**\n * The GenericKeyset is an abstract class that sets-up the interface and partial implementation\n * of a keyset-paginated cursor with two parts. There are three types involved:\n * - Result: a raw result (i.e. a row from the db) containing data that will make-up a cursor.\n * - E.g. { createdAt: '2022-01-01T12:00:00Z', cid: 'bafyx' }\n * - LabeledResult: a Result processed such that the \"primary\" and \"secondary\" parts of the cursor are labeled.\n * - E.g. { primary: '2022-01-01T12:00:00Z', secondary: 'bafyx' }\n * - Cursor: the two string parts that make-up the packed/string cursor.\n * - E.g. packed cursor '1641038400000__bafyx' in parts { primary: '1641038400000', secondary: 'bafyx' }\n *\n * These types relate as such. Implementers define the relations marked with a *:\n * Result -*-> LabeledResult <-*-> Cursor <--> packed/string cursor\n * ↳ SQL Condition\n */\nexport abstract class GenericKeyset<R, LR extends KeysetLabeledResult> {\n constructor(\n public primary: DbRef,\n public secondary: DbRef,\n ) {}\n abstract labelResult(result: R): LR\n abstract labeledResultToCursor(labeled: LR): KeysetCursor\n abstract cursorToLabeledResult(cursor: KeysetCursor): LR\n packFromResult(results: R | R[]): string | undefined {\n const result = Array.isArray(results) ? results.at(-1) : results\n if (!result) return\n return this.pack(this.labelResult(result))\n }\n pack(labeled?: LR): string | undefined {\n if (!labeled) return\n const cursor = this.labeledResultToCursor(labeled)\n return this.packCursor(cursor)\n }\n unpack(cursorStr?: string): LR | undefined {\n const cursor = this.unpackCursor(cursorStr)\n if (!cursor) return\n return this.cursorToLabeledResult(cursor)\n }\n packCursor(cursor?: KeysetCursor): string | undefined {\n if (!cursor) return\n return `${cursor.primary}__${cursor.secondary}`\n }\n unpackCursor(cursorStr?: string): KeysetCursor | undefined {\n if (!cursorStr) return\n const result = cursorStr.split('__')\n const [primary, secondary, ...others] = result\n if (!primary || !secondary || others.length > 0) {\n throw new InvalidRequestError('Malformed cursor')\n }\n return {\n primary,\n secondary,\n }\n }\n getSql(labeled?: LR, direction?: 'asc' | 'desc', tryIndex?: boolean) {\n if (labeled === undefined) return\n if (tryIndex) {\n // The tryIndex param will likely disappear and become the default implementation: here for now for gradual rollout query-by-query.\n if (direction === 'asc') {\n return sql<SqlBool>`((${this.primary}, ${this.secondary}) > (${labeled.primary}, ${labeled.secondary}))`\n } else {\n return sql<SqlBool>`((${this.primary}, ${this.secondary}) < (${labeled.primary}, ${labeled.secondary}))`\n }\n } else {\n // @NOTE this implementation can struggle to use an index on (primary, secondary) for pagination due to the \"or\" usage.\n if (direction === 'asc') {\n return sql<SqlBool>`((${this.primary} > ${labeled.primary}) or (${this.primary} = ${labeled.primary} and ${this.secondary} > ${labeled.secondary}))`\n } else {\n return sql<SqlBool>`((${this.primary} < ${labeled.primary}) or (${this.primary} = ${labeled.primary} and ${this.secondary} < ${labeled.secondary}))`\n }\n }\n }\n paginate<QB extends AnyQb>(\n qb: QB,\n opts: {\n limit?: number\n cursor?: string\n direction?: 'asc' | 'desc'\n tryIndex?: boolean\n // By default, pg does nullsFirst\n nullsLast?: boolean\n },\n ): QB {\n const { limit, cursor, direction = 'desc', tryIndex, nullsLast } = opts\n const keysetSql = this.getSql(this.unpack(cursor), direction, tryIndex)\n return qb\n .$if(!!limit, (q) => q.limit(limit as number))\n .$if(!nullsLast, (q) =>\n q.orderBy(this.primary, direction).orderBy(this.secondary, direction),\n )\n .$if(!!nullsLast, (q) =>\n q\n .orderBy(\n direction === 'asc'\n ? sql`${this.primary} asc nulls last`\n : sql`${this.primary} desc nulls last`,\n )\n .orderBy(\n direction === 'asc'\n ? sql`${this.secondary} asc nulls last`\n : sql`${this.secondary} desc nulls last`,\n ),\n )\n .$if(!!keysetSql, (qb) => (keysetSql ? qb.where(keysetSql) : qb)) as QB\n }\n}\n\ntype SortAtCidResult = { sortAt: string; cid: string }\ntype TimeCidLabeledResult = KeysetCursor\n\nexport class TimeCidKeyset<\n TimeCidResult = SortAtCidResult,\n> extends GenericKeyset<TimeCidResult, TimeCidLabeledResult> {\n labelResult(result: TimeCidResult): TimeCidLabeledResult\n labelResult<TimeCidResult extends SortAtCidResult>(result: TimeCidResult) {\n return { primary: result.sortAt, secondary: result.cid }\n }\n labeledResultToCursor(labeled: TimeCidLabeledResult) {\n return {\n primary: new Date(labeled.primary).getTime().toString(),\n secondary: labeled.secondary,\n }\n }\n cursorToLabeledResult(cursor: KeysetCursor) {\n const primaryDate = new Date(parseInt(cursor.primary, 10))\n if (isNaN(primaryDate.getTime())) {\n throw new InvalidRequestError('Malformed cursor')\n }\n return {\n primary: primaryDate.toISOString(),\n secondary: cursor.secondary,\n }\n }\n}\n\nexport class CreatedAtDidKeyset extends TimeCidKeyset<{\n createdAt: string\n did: string // dids are treated identically to cids in TimeCidKeyset\n}> {\n labelResult(result: { createdAt: string; did: string }) {\n return { primary: result.createdAt, secondary: result.did }\n }\n}\n\nexport class IndexedAtDidKeyset extends TimeCidKeyset<{\n indexedAt: string\n did: string // dids are treated identically to cids in TimeCidKeyset\n}> {\n labelResult(result: { indexedAt: string; did: string }) {\n return { primary: result.indexedAt, secondary: result.did }\n }\n}\n\n/**\n * This is being deprecated. Use {@link GenericKeyset#paginate} instead.\n */\nexport const paginate = <\n QB extends AnyQb,\n K extends GenericKeyset<unknown, any>,\n>(\n qb: QB,\n opts: {\n limit?: number\n cursor?: string\n direction?: 'asc' | 'desc'\n keyset: K\n tryIndex?: boolean\n // By default, pg does nullsFirst\n nullsLast?: boolean\n },\n): QB => {\n return opts.keyset.paginate(qb, opts)\n}\n\ntype SingleKeyCursor = {\n primary: string\n}\n\ntype SingleKeyLabeledResult = {\n primary: string | number\n}\n\n/**\n * GenericSingleKey is similar to {@link GenericKeyset} but for a single key cursor.\n */\nexport abstract class GenericSingleKey<R, LR extends SingleKeyLabeledResult> {\n constructor(public primary: DbRef) {}\n abstract labelResult(result: R): LR\n abstract labeledResultToCursor(labeled: LR): SingleKeyCursor\n abstract cursorToLabeledResult(cursor: SingleKeyCursor): LR\n packFromResult(results: R | R[]): string | undefined {\n const result = Array.isArray(results) ? results.at(-1) : results\n if (!result) return\n return this.pack(this.labelResult(result))\n }\n pack(labeled?: LR): string | undefined {\n if (!labeled) return\n const cursor = this.labeledResultToCursor(labeled)\n return this.packCursor(cursor)\n }\n unpack(cursorStr?: string): LR | undefined {\n const cursor = this.unpackCursor(cursorStr)\n if (!cursor) return\n return this.cursorToLabeledResult(cursor)\n }\n packCursor(cursor?: SingleKeyCursor): string | undefined {\n if (!cursor) return\n return cursor.primary\n }\n unpackCursor(cursorStr?: string): SingleKeyCursor | undefined {\n if (!cursorStr) return\n const result = cursorStr.split('__')\n const [primary, ...others] = result\n if (!primary || others.length > 0) {\n throw new InvalidRequestError('Malformed cursor')\n }\n return {\n primary,\n }\n }\n getSql(labeled?: LR, direction?: 'asc' | 'desc') {\n if (labeled === undefined) return\n if (direction === 'asc') {\n return sql<SqlBool>`${this.primary} > ${labeled.primary}`\n }\n return sql<SqlBool>`${this.primary} < ${labeled.primary}`\n }\n paginate<QB extends AnyQb>(\n qb: QB,\n opts: {\n limit?: number\n cursor?: string\n direction?: 'asc' | 'desc'\n // By default, pg does nullsFirst\n nullsLast?: boolean\n },\n ): QB {\n const { limit, cursor, direction = 'desc', nullsLast } = opts\n const keySql = this.getSql(this.unpack(cursor), direction)\n return qb\n .$if(!!limit, (q) => q.limit(limit as number))\n .$if(!nullsLast, (q) => q.orderBy(this.primary, direction))\n .$if(!!nullsLast, (q) =>\n q.orderBy(\n direction === 'asc'\n ? sql`${this.primary} asc nulls last`\n : sql`${this.primary} desc nulls last`,\n ),\n )\n .$if(!!keySql, (qb) => (keySql ? qb.where(keySql) : qb)) as QB\n }\n}\n\ntype SortAtResult = { sortAt: string }\ntype TimeLabeledResult = SingleKeyCursor\n\nexport class IsoTimeKey<TimeResult = SortAtResult> extends GenericSingleKey<\n TimeResult,\n TimeLabeledResult\n> {\n labelResult(result: TimeResult): TimeLabeledResult\n labelResult<TimeResult extends SortAtResult>(result: TimeResult) {\n return { primary: result.sortAt }\n }\n labeledResultToCursor(labeled: TimeLabeledResult) {\n return {\n primary: new Date(labeled.primary).toISOString(),\n }\n }\n cursorToLabeledResult(cursor: SingleKeyCursor) {\n const primaryDate = new Date(cursor.primary)\n if (isNaN(primaryDate.getTime())) {\n throw new InvalidRequestError('Malformed cursor')\n }\n return {\n primary: primaryDate.toISOString(),\n }\n }\n}\n\nexport class IsoSortAtKey extends IsoTimeKey<{\n sortAt: string\n}> {\n labelResult(result: { sortAt: string }) {\n return { primary: result.sortAt }\n }\n}\n\nexport class IsoUpdatedAtKey extends IsoTimeKey<{\n updatedAt: string\n}> {\n labelResult(result: { updatedAt: string }) {\n return { primary: result.updatedAt }\n }\n}\n\ntype KeyResult = { key: string }\ntype RkeyLabeledResult = SingleKeyCursor\n\nexport class RkeyKey<RkeyResult = KeyResult> extends GenericSingleKey<\n RkeyResult,\n RkeyLabeledResult\n> {\n labelResult(result: RkeyResult): RkeyLabeledResult\n labelResult<RkeyResult extends KeyResult>(result: RkeyResult) {\n return { primary: result }\n }\n labeledResultToCursor(labeled: RkeyLabeledResult) {\n return {\n primary: labeled.primary,\n }\n }\n cursorToLabeledResult(cursor: SingleKeyCursor) {\n try {\n ensureValidRecordKey(cursor.primary)\n return {\n primary: cursor.primary,\n }\n } catch {\n throw new InvalidRequestError('Malformed cursor')\n }\n }\n}\n\nexport class StashKeyKey extends RkeyKey<{\n key: string\n}> {\n labelResult(result: { key: string }) {\n return { primary: result.key }\n }\n}\n"]}
1
+ {"version":3,"file":"pagination.js","sourceRoot":"","sources":["../../../../src/data-plane/server/db/pagination.ts"],"names":[],"mappings":"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","sourcesContent":["import { type SqlBool, sql } from 'kysely'\nimport { ensureValidRecordKey } from '@atproto/syntax'\nimport { InvalidRequestError } from '@atproto/xrpc-server'\nimport type { AnyQb, DbRef } from './util.js'\n\ntype KeysetCursor = { primary: string; secondary: string }\ntype KeysetLabeledResult = {\n primary: string | number\n secondary: string | number\n}\n\n/**\n * The GenericKeyset is an abstract class that sets-up the interface and partial implementation\n * of a keyset-paginated cursor with two parts. There are three types involved:\n * - Result: a raw result (i.e. a row from the db) containing data that will make-up a cursor.\n * - E.g. { createdAt: '2022-01-01T12:00:00Z', cid: 'bafyx' }\n * - LabeledResult: a Result processed such that the \"primary\" and \"secondary\" parts of the cursor are labeled.\n * - E.g. { primary: '2022-01-01T12:00:00Z', secondary: 'bafyx' }\n * - Cursor: the two string parts that make-up the packed/string cursor.\n * - E.g. packed cursor '1641038400000__bafyx' in parts { primary: '1641038400000', secondary: 'bafyx' }\n *\n * These types relate as such. Implementers define the relations marked with a *:\n * Result -*-> LabeledResult <-*-> Cursor <--> packed/string cursor\n * ↳ SQL Condition\n */\nexport abstract class GenericKeyset<R, LR extends KeysetLabeledResult> {\n constructor(\n public primary: DbRef,\n public secondary: DbRef,\n ) {}\n abstract labelResult(result: R): LR\n abstract labeledResultToCursor(labeled: LR): KeysetCursor\n abstract cursorToLabeledResult(cursor: KeysetCursor): LR\n packFromResult(results: R | R[]): string | undefined {\n const result = Array.isArray(results) ? results.at(-1) : results\n if (!result) return\n return this.pack(this.labelResult(result))\n }\n page<Result extends R>(\n results: Result[],\n limit: number,\n ): { items: Result[]; cursor?: string } {\n const items = results.slice(0, limit)\n return {\n items,\n cursor:\n results.length > limit && items.length\n ? this.packFromResult(items[items.length - 1])\n : undefined,\n }\n }\n pack(labeled?: LR): string | undefined {\n if (!labeled) return\n const cursor = this.labeledResultToCursor(labeled)\n return this.packCursor(cursor)\n }\n unpack(cursorStr?: string): LR | undefined {\n const cursor = this.unpackCursor(cursorStr)\n if (!cursor) return\n return this.cursorToLabeledResult(cursor)\n }\n packCursor(cursor?: KeysetCursor): string | undefined {\n if (!cursor) return\n return `${cursor.primary}__${cursor.secondary}`\n }\n unpackCursor(cursorStr?: string): KeysetCursor | undefined {\n if (!cursorStr) return\n const result = cursorStr.split('__')\n const [primary, secondary, ...others] = result\n if (!primary || !secondary || others.length > 0) {\n throw new InvalidRequestError('Malformed cursor')\n }\n return {\n primary,\n secondary,\n }\n }\n getSql(labeled?: LR, direction?: 'asc' | 'desc', tryIndex?: boolean) {\n if (labeled === undefined) return\n if (tryIndex) {\n // The tryIndex param will likely disappear and become the default implementation: here for now for gradual rollout query-by-query.\n if (direction === 'asc') {\n return sql<SqlBool>`((${this.primary}, ${this.secondary}) > (${labeled.primary}, ${labeled.secondary}))`\n } else {\n return sql<SqlBool>`((${this.primary}, ${this.secondary}) < (${labeled.primary}, ${labeled.secondary}))`\n }\n } else {\n // @NOTE this implementation can struggle to use an index on (primary, secondary) for pagination due to the \"or\" usage.\n if (direction === 'asc') {\n return sql<SqlBool>`((${this.primary} > ${labeled.primary}) or (${this.primary} = ${labeled.primary} and ${this.secondary} > ${labeled.secondary}))`\n } else {\n return sql<SqlBool>`((${this.primary} < ${labeled.primary}) or (${this.primary} = ${labeled.primary} and ${this.secondary} < ${labeled.secondary}))`\n }\n }\n }\n paginate<QB extends AnyQb>(\n qb: QB,\n opts: {\n limit?: number\n cursor?: string\n direction?: 'asc' | 'desc'\n tryIndex?: boolean\n // By default, pg does nullsFirst\n nullsLast?: boolean\n },\n ): QB {\n const { limit, cursor, direction = 'desc', tryIndex, nullsLast } = opts\n const keysetSql = this.getSql(this.unpack(cursor), direction, tryIndex)\n return qb\n .$if(!!limit, (q) => q.limit((limit as number) + 1))\n .$if(!nullsLast, (q) =>\n q.orderBy(this.primary, direction).orderBy(this.secondary, direction),\n )\n .$if(!!nullsLast, (q) =>\n q\n .orderBy(\n direction === 'asc'\n ? sql`${this.primary} asc nulls last`\n : sql`${this.primary} desc nulls last`,\n )\n .orderBy(\n direction === 'asc'\n ? sql`${this.secondary} asc nulls last`\n : sql`${this.secondary} desc nulls last`,\n ),\n )\n .$if(!!keysetSql, (qb) => (keysetSql ? qb.where(keysetSql) : qb)) as QB\n }\n}\n\ntype SortAtCidResult = { sortAt: string; cid: string }\ntype TimeCidLabeledResult = KeysetCursor\n\nexport class TimeCidKeyset<\n TimeCidResult = SortAtCidResult,\n> extends GenericKeyset<TimeCidResult, TimeCidLabeledResult> {\n labelResult(result: TimeCidResult): TimeCidLabeledResult\n labelResult<TimeCidResult extends SortAtCidResult>(result: TimeCidResult) {\n return { primary: result.sortAt, secondary: result.cid }\n }\n labeledResultToCursor(labeled: TimeCidLabeledResult) {\n return {\n primary: new Date(labeled.primary).getTime().toString(),\n secondary: labeled.secondary,\n }\n }\n cursorToLabeledResult(cursor: KeysetCursor) {\n const primaryDate = new Date(parseInt(cursor.primary, 10))\n if (isNaN(primaryDate.getTime())) {\n throw new InvalidRequestError('Malformed cursor')\n }\n return {\n primary: primaryDate.toISOString(),\n secondary: cursor.secondary,\n }\n }\n}\n\nexport class CreatedAtDidKeyset extends TimeCidKeyset<{\n createdAt: string\n did: string // dids are treated identically to cids in TimeCidKeyset\n}> {\n labelResult(result: { createdAt: string; did: string }) {\n return { primary: result.createdAt, secondary: result.did }\n }\n}\n\nexport class IndexedAtDidKeyset extends TimeCidKeyset<{\n indexedAt: string\n did: string // dids are treated identically to cids in TimeCidKeyset\n}> {\n labelResult(result: { indexedAt: string; did: string }) {\n return { primary: result.indexedAt, secondary: result.did }\n }\n}\n\n/**\n * This is being deprecated. Use {@link GenericKeyset#paginate} instead.\n */\nexport const paginate = <\n QB extends AnyQb,\n K extends GenericKeyset<unknown, any>,\n>(\n qb: QB,\n opts: {\n limit?: number\n cursor?: string\n direction?: 'asc' | 'desc'\n keyset: K\n tryIndex?: boolean\n // By default, pg does nullsFirst\n nullsLast?: boolean\n },\n): QB => {\n return opts.keyset.paginate(qb, opts)\n}\n\ntype SingleKeyCursor = {\n primary: string\n}\n\ntype SingleKeyLabeledResult = {\n primary: string | number\n}\n\n/**\n * GenericSingleKey is similar to {@link GenericKeyset} but for a single key cursor.\n */\nexport abstract class GenericSingleKey<R, LR extends SingleKeyLabeledResult> {\n constructor(public primary: DbRef) {}\n abstract labelResult(result: R): LR\n abstract labeledResultToCursor(labeled: LR): SingleKeyCursor\n abstract cursorToLabeledResult(cursor: SingleKeyCursor): LR\n packFromResult(results: R | R[]): string | undefined {\n const result = Array.isArray(results) ? results.at(-1) : results\n if (!result) return\n return this.pack(this.labelResult(result))\n }\n page<Result extends R>(\n results: Result[],\n limit: number,\n ): { items: Result[]; cursor?: string } {\n const items = results.slice(0, limit)\n return {\n items,\n cursor:\n results.length > limit && items.length\n ? this.packFromResult(items[items.length - 1])\n : undefined,\n }\n }\n pack(labeled?: LR): string | undefined {\n if (!labeled) return\n const cursor = this.labeledResultToCursor(labeled)\n return this.packCursor(cursor)\n }\n unpack(cursorStr?: string): LR | undefined {\n const cursor = this.unpackCursor(cursorStr)\n if (!cursor) return\n return this.cursorToLabeledResult(cursor)\n }\n packCursor(cursor?: SingleKeyCursor): string | undefined {\n if (!cursor) return\n return cursor.primary\n }\n unpackCursor(cursorStr?: string): SingleKeyCursor | undefined {\n if (!cursorStr) return\n const result = cursorStr.split('__')\n const [primary, ...others] = result\n if (!primary || others.length > 0) {\n throw new InvalidRequestError('Malformed cursor')\n }\n return {\n primary,\n }\n }\n getSql(labeled?: LR, direction?: 'asc' | 'desc') {\n if (labeled === undefined) return\n if (direction === 'asc') {\n return sql<SqlBool>`${this.primary} > ${labeled.primary}`\n }\n return sql<SqlBool>`${this.primary} < ${labeled.primary}`\n }\n paginate<QB extends AnyQb>(\n qb: QB,\n opts: {\n limit?: number\n cursor?: string\n direction?: 'asc' | 'desc'\n // By default, pg does nullsFirst\n nullsLast?: boolean\n },\n ): QB {\n const { limit, cursor, direction = 'desc', nullsLast } = opts\n const keySql = this.getSql(this.unpack(cursor), direction)\n return qb\n .$if(!!limit, (q) => q.limit((limit as number) + 1))\n .$if(!nullsLast, (q) => q.orderBy(this.primary, direction))\n .$if(!!nullsLast, (q) =>\n q.orderBy(\n direction === 'asc'\n ? sql`${this.primary} asc nulls last`\n : sql`${this.primary} desc nulls last`,\n ),\n )\n .$if(!!keySql, (qb) => (keySql ? qb.where(keySql) : qb)) as QB\n }\n}\n\ntype SortAtResult = { sortAt: string }\ntype TimeLabeledResult = SingleKeyCursor\n\nexport class IsoTimeKey<TimeResult = SortAtResult> extends GenericSingleKey<\n TimeResult,\n TimeLabeledResult\n> {\n labelResult(result: TimeResult): TimeLabeledResult\n labelResult<TimeResult extends SortAtResult>(result: TimeResult) {\n return { primary: result.sortAt }\n }\n labeledResultToCursor(labeled: TimeLabeledResult) {\n return {\n primary: new Date(labeled.primary).toISOString(),\n }\n }\n cursorToLabeledResult(cursor: SingleKeyCursor) {\n const primaryDate = new Date(cursor.primary)\n if (isNaN(primaryDate.getTime())) {\n throw new InvalidRequestError('Malformed cursor')\n }\n return {\n primary: primaryDate.toISOString(),\n }\n }\n}\n\nexport class IsoSortAtKey extends IsoTimeKey<{\n sortAt: string\n}> {\n labelResult(result: { sortAt: string }) {\n return { primary: result.sortAt }\n }\n}\n\nexport class IsoUpdatedAtKey extends IsoTimeKey<{\n updatedAt: string\n}> {\n labelResult(result: { updatedAt: string }) {\n return { primary: result.updatedAt }\n }\n}\n\ntype KeyResult = { key: string }\ntype RkeyLabeledResult = SingleKeyCursor\n\nexport class RkeyKey<RkeyResult = KeyResult> extends GenericSingleKey<\n RkeyResult,\n RkeyLabeledResult\n> {\n labelResult(result: RkeyResult): RkeyLabeledResult\n labelResult<RkeyResult extends KeyResult>(result: RkeyResult) {\n return { primary: result }\n }\n labeledResultToCursor(labeled: RkeyLabeledResult) {\n return {\n primary: labeled.primary,\n }\n }\n cursorToLabeledResult(cursor: SingleKeyCursor) {\n try {\n ensureValidRecordKey(cursor.primary)\n return {\n primary: cursor.primary,\n }\n } catch {\n throw new InvalidRequestError('Malformed cursor')\n }\n }\n}\n\nexport class StashKeyKey extends RkeyKey<{\n key: string\n}> {\n labelResult(result: { key: string }) {\n return { primary: result.key }\n }\n}\n"]}