@atproto/bsky 0.0.243 → 0.0.245

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 (405) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/dist/api/app/bsky/actor/searchActorsTypeahead.js +5 -3
  3. package/dist/api/app/bsky/actor/searchActorsTypeahead.js.map +1 -1
  4. package/dist/api/app/bsky/feed/searchPostsV2.d.ts +4 -0
  5. package/dist/api/app/bsky/feed/searchPostsV2.d.ts.map +1 -0
  6. package/dist/api/app/bsky/feed/searchPostsV2.js +169 -0
  7. package/dist/api/app/bsky/feed/searchPostsV2.js.map +1 -0
  8. package/dist/api/app/bsky/notification/putPreferencesV2.js +4 -1
  9. package/dist/api/app/bsky/notification/putPreferencesV2.js.map +1 -1
  10. package/dist/api/app/bsky/notification/util.d.ts +1 -0
  11. package/dist/api/app/bsky/notification/util.d.ts.map +1 -1
  12. package/dist/api/app/bsky/notification/util.js +7 -7
  13. package/dist/api/app/bsky/notification/util.js.map +1 -1
  14. package/dist/api/blob-dispatcher.d.ts.map +1 -1
  15. package/dist/api/blob-dispatcher.js +9 -8
  16. package/dist/api/blob-dispatcher.js.map +1 -1
  17. package/dist/api/blob-resolver.d.ts +1 -1
  18. package/dist/api/blob-resolver.d.ts.map +1 -1
  19. package/dist/api/blob-resolver.js +0 -1
  20. package/dist/api/blob-resolver.js.map +1 -1
  21. package/dist/api/index.d.ts.map +1 -1
  22. package/dist/api/index.js +2 -0
  23. package/dist/api/index.js.map +1 -1
  24. package/dist/data-plane/bsync/index.d.ts +2 -0
  25. package/dist/data-plane/bsync/index.d.ts.map +1 -1
  26. package/dist/data-plane/bsync/index.js +7 -10
  27. package/dist/data-plane/bsync/index.js.map +1 -1
  28. package/dist/data-plane/server/background.d.ts +12 -8
  29. package/dist/data-plane/server/background.d.ts.map +1 -1
  30. package/dist/data-plane/server/background.js +32 -14
  31. package/dist/data-plane/server/background.js.map +1 -1
  32. package/dist/data-plane/server/index.d.ts +2 -0
  33. package/dist/data-plane/server/index.d.ts.map +1 -1
  34. package/dist/data-plane/server/index.js +7 -10
  35. package/dist/data-plane/server/index.js.map +1 -1
  36. package/dist/data-plane/server/indexing/index.d.ts +2 -2
  37. package/dist/data-plane/server/indexing/index.d.ts.map +1 -1
  38. package/dist/data-plane/server/indexing/index.js.map +1 -1
  39. package/dist/data-plane/server/indexing/plugins/block.d.ts +1 -1
  40. package/dist/data-plane/server/indexing/plugins/block.d.ts.map +1 -1
  41. package/dist/data-plane/server/indexing/plugins/block.js.map +1 -1
  42. package/dist/data-plane/server/indexing/plugins/chat-declaration.d.ts +1 -1
  43. package/dist/data-plane/server/indexing/plugins/chat-declaration.d.ts.map +1 -1
  44. package/dist/data-plane/server/indexing/plugins/chat-declaration.js.map +1 -1
  45. package/dist/data-plane/server/indexing/plugins/feed-generator.d.ts +1 -1
  46. package/dist/data-plane/server/indexing/plugins/feed-generator.d.ts.map +1 -1
  47. package/dist/data-plane/server/indexing/plugins/feed-generator.js.map +1 -1
  48. package/dist/data-plane/server/indexing/plugins/follow.d.ts +1 -1
  49. package/dist/data-plane/server/indexing/plugins/follow.d.ts.map +1 -1
  50. package/dist/data-plane/server/indexing/plugins/follow.js.map +1 -1
  51. package/dist/data-plane/server/indexing/plugins/germ-declaration.d.ts +1 -1
  52. package/dist/data-plane/server/indexing/plugins/germ-declaration.d.ts.map +1 -1
  53. package/dist/data-plane/server/indexing/plugins/germ-declaration.js.map +1 -1
  54. package/dist/data-plane/server/indexing/plugins/labeler.d.ts +1 -1
  55. package/dist/data-plane/server/indexing/plugins/labeler.d.ts.map +1 -1
  56. package/dist/data-plane/server/indexing/plugins/labeler.js.map +1 -1
  57. package/dist/data-plane/server/indexing/plugins/like.d.ts +1 -1
  58. package/dist/data-plane/server/indexing/plugins/like.d.ts.map +1 -1
  59. package/dist/data-plane/server/indexing/plugins/like.js.map +1 -1
  60. package/dist/data-plane/server/indexing/plugins/list-block.d.ts +1 -1
  61. package/dist/data-plane/server/indexing/plugins/list-block.d.ts.map +1 -1
  62. package/dist/data-plane/server/indexing/plugins/list-block.js.map +1 -1
  63. package/dist/data-plane/server/indexing/plugins/list-item.d.ts +1 -1
  64. package/dist/data-plane/server/indexing/plugins/list-item.d.ts.map +1 -1
  65. package/dist/data-plane/server/indexing/plugins/list-item.js.map +1 -1
  66. package/dist/data-plane/server/indexing/plugins/list.d.ts +1 -1
  67. package/dist/data-plane/server/indexing/plugins/list.d.ts.map +1 -1
  68. package/dist/data-plane/server/indexing/plugins/list.js.map +1 -1
  69. package/dist/data-plane/server/indexing/plugins/notif-declaration.d.ts +1 -1
  70. package/dist/data-plane/server/indexing/plugins/notif-declaration.d.ts.map +1 -1
  71. package/dist/data-plane/server/indexing/plugins/notif-declaration.js.map +1 -1
  72. package/dist/data-plane/server/indexing/plugins/post-gate.d.ts +1 -1
  73. package/dist/data-plane/server/indexing/plugins/post-gate.d.ts.map +1 -1
  74. package/dist/data-plane/server/indexing/plugins/post-gate.js.map +1 -1
  75. package/dist/data-plane/server/indexing/plugins/post.d.ts +1 -1
  76. package/dist/data-plane/server/indexing/plugins/post.d.ts.map +1 -1
  77. package/dist/data-plane/server/indexing/plugins/post.js.map +1 -1
  78. package/dist/data-plane/server/indexing/plugins/profile.d.ts +1 -1
  79. package/dist/data-plane/server/indexing/plugins/profile.d.ts.map +1 -1
  80. package/dist/data-plane/server/indexing/plugins/profile.js.map +1 -1
  81. package/dist/data-plane/server/indexing/plugins/repost.d.ts +1 -1
  82. package/dist/data-plane/server/indexing/plugins/repost.d.ts.map +1 -1
  83. package/dist/data-plane/server/indexing/plugins/repost.js.map +1 -1
  84. package/dist/data-plane/server/indexing/plugins/starter-pack.d.ts +1 -1
  85. package/dist/data-plane/server/indexing/plugins/starter-pack.d.ts.map +1 -1
  86. package/dist/data-plane/server/indexing/plugins/starter-pack.js.map +1 -1
  87. package/dist/data-plane/server/indexing/plugins/status.d.ts +1 -1
  88. package/dist/data-plane/server/indexing/plugins/status.d.ts.map +1 -1
  89. package/dist/data-plane/server/indexing/plugins/status.js.map +1 -1
  90. package/dist/data-plane/server/indexing/plugins/thread-gate.d.ts +1 -1
  91. package/dist/data-plane/server/indexing/plugins/thread-gate.d.ts.map +1 -1
  92. package/dist/data-plane/server/indexing/plugins/thread-gate.js.map +1 -1
  93. package/dist/data-plane/server/indexing/plugins/verification.d.ts +1 -1
  94. package/dist/data-plane/server/indexing/plugins/verification.d.ts.map +1 -1
  95. package/dist/data-plane/server/indexing/plugins/verification.js.map +1 -1
  96. package/dist/data-plane/server/indexing/processor.d.ts +1 -1
  97. package/dist/data-plane/server/indexing/processor.d.ts.map +1 -1
  98. package/dist/data-plane/server/indexing/processor.js.map +1 -1
  99. package/dist/data-plane/server/routes/notifs.d.ts.map +1 -1
  100. package/dist/data-plane/server/routes/notifs.js +1 -8
  101. package/dist/data-plane/server/routes/notifs.js.map +1 -1
  102. package/dist/data-plane/server/routes/search.js +3 -2
  103. package/dist/data-plane/server/routes/search.js.map +1 -1
  104. package/dist/data-plane/server/subscription.d.ts +13 -12
  105. package/dist/data-plane/server/subscription.d.ts.map +1 -1
  106. package/dist/data-plane/server/subscription.js +59 -26
  107. package/dist/data-plane/server/subscription.js.map +1 -1
  108. package/dist/feature-gates/index.d.ts +2 -1
  109. package/dist/feature-gates/index.d.ts.map +1 -1
  110. package/dist/feature-gates/index.js +9 -6
  111. package/dist/feature-gates/index.js.map +1 -1
  112. package/dist/feature-gates/metrics.d.ts +3 -3
  113. package/dist/feature-gates/metrics.d.ts.map +1 -1
  114. package/dist/feature-gates/metrics.js +8 -8
  115. package/dist/feature-gates/metrics.js.map +1 -1
  116. package/dist/index.d.ts +1 -0
  117. package/dist/index.d.ts.map +1 -1
  118. package/dist/index.js +16 -7
  119. package/dist/index.js.map +1 -1
  120. package/dist/lexicons/app/bsky/authFullApp.defs.d.ts.map +1 -1
  121. package/dist/lexicons/app/bsky/authFullApp.defs.js +1 -0
  122. package/dist/lexicons/app/bsky/authFullApp.defs.js.map +1 -1
  123. package/dist/lexicons/app/bsky/authViewAll.defs.d.ts.map +1 -1
  124. package/dist/lexicons/app/bsky/authViewAll.defs.js +1 -0
  125. package/dist/lexicons/app/bsky/authViewAll.defs.js.map +1 -1
  126. package/dist/lexicons/app/bsky/feed/searchPostsV2.d.ts +3 -0
  127. package/dist/lexicons/app/bsky/feed/searchPostsV2.d.ts.map +1 -0
  128. package/dist/lexicons/app/bsky/feed/searchPostsV2.defs.d.ts +158 -0
  129. package/dist/lexicons/app/bsky/feed/searchPostsV2.defs.d.ts.map +1 -0
  130. package/dist/lexicons/app/bsky/feed/searchPostsV2.defs.js +73 -0
  131. package/dist/lexicons/app/bsky/feed/searchPostsV2.defs.js.map +1 -0
  132. package/dist/lexicons/app/bsky/feed/searchPostsV2.js +6 -0
  133. package/dist/lexicons/app/bsky/feed/searchPostsV2.js.map +1 -0
  134. package/dist/lexicons/app/bsky/feed.d.ts +1 -0
  135. package/dist/lexicons/app/bsky/feed.d.ts.map +1 -1
  136. package/dist/lexicons/app/bsky/feed.js +1 -0
  137. package/dist/lexicons/app/bsky/feed.js.map +1 -1
  138. package/dist/lexicons/app/bsky/notification/defs.defs.d.ts +5 -0
  139. package/dist/lexicons/app/bsky/notification/defs.defs.d.ts.map +1 -1
  140. package/dist/lexicons/app/bsky/notification/defs.defs.js +1 -0
  141. package/dist/lexicons/app/bsky/notification/defs.defs.js.map +1 -1
  142. package/dist/lexicons/chat/bsky/actor/declaration.defs.d.ts +1 -1
  143. package/dist/lexicons/chat/bsky/actor/declaration.defs.js.map +1 -1
  144. package/dist/lexicons/chat/bsky/actor/defs.defs.d.ts +4 -6
  145. package/dist/lexicons/chat/bsky/actor/defs.defs.d.ts.map +1 -1
  146. package/dist/lexicons/chat/bsky/actor/defs.defs.js +2 -3
  147. package/dist/lexicons/chat/bsky/actor/defs.defs.js.map +1 -1
  148. package/dist/lexicons/chat/bsky/convo/defs.defs.d.ts +64 -70
  149. package/dist/lexicons/chat/bsky/convo/defs.defs.d.ts.map +1 -1
  150. package/dist/lexicons/chat/bsky/convo/defs.defs.js +32 -35
  151. package/dist/lexicons/chat/bsky/convo/defs.defs.js.map +1 -1
  152. package/dist/lexicons/chat/bsky/convo/getUnreadCounts.defs.d.ts +1 -1
  153. package/dist/lexicons/chat/bsky/convo/getUnreadCounts.defs.d.ts.map +1 -1
  154. package/dist/lexicons/chat/bsky/convo/getUnreadCounts.defs.js +1 -1
  155. package/dist/lexicons/chat/bsky/convo/getUnreadCounts.defs.js.map +1 -1
  156. package/dist/lexicons/chat/bsky/convo/listConvoRequests.defs.d.ts +1 -1
  157. package/dist/lexicons/chat/bsky/convo/listConvoRequests.defs.d.ts.map +1 -1
  158. package/dist/lexicons/chat/bsky/convo/listConvoRequests.defs.js +1 -1
  159. package/dist/lexicons/chat/bsky/convo/listConvoRequests.defs.js.map +1 -1
  160. package/dist/lexicons/chat/bsky/convo/lockConvo.defs.d.ts +1 -1
  161. package/dist/lexicons/chat/bsky/convo/lockConvo.defs.d.ts.map +1 -1
  162. package/dist/lexicons/chat/bsky/convo/lockConvo.defs.js +1 -1
  163. package/dist/lexicons/chat/bsky/convo/lockConvo.defs.js.map +1 -1
  164. package/dist/lexicons/chat/bsky/convo/unlockConvo.defs.d.ts +1 -1
  165. package/dist/lexicons/chat/bsky/convo/unlockConvo.defs.d.ts.map +1 -1
  166. package/dist/lexicons/chat/bsky/convo/unlockConvo.defs.js +1 -1
  167. package/dist/lexicons/chat/bsky/convo/unlockConvo.defs.js.map +1 -1
  168. package/dist/lexicons/chat/bsky/group/addMembers.defs.d.ts +1 -1
  169. package/dist/lexicons/chat/bsky/group/addMembers.defs.d.ts.map +1 -1
  170. package/dist/lexicons/chat/bsky/group/addMembers.defs.js +1 -1
  171. package/dist/lexicons/chat/bsky/group/addMembers.defs.js.map +1 -1
  172. package/dist/lexicons/chat/bsky/group/approveJoinRequest.defs.d.ts +1 -1
  173. package/dist/lexicons/chat/bsky/group/approveJoinRequest.defs.d.ts.map +1 -1
  174. package/dist/lexicons/chat/bsky/group/approveJoinRequest.defs.js +1 -1
  175. package/dist/lexicons/chat/bsky/group/approveJoinRequest.defs.js.map +1 -1
  176. package/dist/lexicons/chat/bsky/group/createGroup.defs.d.ts +1 -1
  177. package/dist/lexicons/chat/bsky/group/createGroup.defs.d.ts.map +1 -1
  178. package/dist/lexicons/chat/bsky/group/createGroup.defs.js +1 -1
  179. package/dist/lexicons/chat/bsky/group/createGroup.defs.js.map +1 -1
  180. package/dist/lexicons/chat/bsky/group/createJoinLink.defs.d.ts +1 -1
  181. package/dist/lexicons/chat/bsky/group/createJoinLink.defs.d.ts.map +1 -1
  182. package/dist/lexicons/chat/bsky/group/createJoinLink.defs.js +1 -1
  183. package/dist/lexicons/chat/bsky/group/createJoinLink.defs.js.map +1 -1
  184. package/dist/lexicons/chat/bsky/group/disableJoinLink.defs.d.ts +1 -1
  185. package/dist/lexicons/chat/bsky/group/disableJoinLink.defs.d.ts.map +1 -1
  186. package/dist/lexicons/chat/bsky/group/disableJoinLink.defs.js +1 -1
  187. package/dist/lexicons/chat/bsky/group/disableJoinLink.defs.js.map +1 -1
  188. package/dist/lexicons/chat/bsky/group/editGroup.defs.d.ts +1 -1
  189. package/dist/lexicons/chat/bsky/group/editGroup.defs.d.ts.map +1 -1
  190. package/dist/lexicons/chat/bsky/group/editGroup.defs.js +1 -1
  191. package/dist/lexicons/chat/bsky/group/editGroup.defs.js.map +1 -1
  192. package/dist/lexicons/chat/bsky/group/editJoinLink.defs.d.ts +1 -1
  193. package/dist/lexicons/chat/bsky/group/editJoinLink.defs.d.ts.map +1 -1
  194. package/dist/lexicons/chat/bsky/group/editJoinLink.defs.js +1 -1
  195. package/dist/lexicons/chat/bsky/group/editJoinLink.defs.js.map +1 -1
  196. package/dist/lexicons/chat/bsky/group/enableJoinLink.defs.d.ts +1 -1
  197. package/dist/lexicons/chat/bsky/group/enableJoinLink.defs.d.ts.map +1 -1
  198. package/dist/lexicons/chat/bsky/group/enableJoinLink.defs.js +1 -1
  199. package/dist/lexicons/chat/bsky/group/enableJoinLink.defs.js.map +1 -1
  200. package/dist/lexicons/chat/bsky/group/getJoinLinkPreviews.defs.d.ts +1 -1
  201. package/dist/lexicons/chat/bsky/group/getJoinLinkPreviews.defs.d.ts.map +1 -1
  202. package/dist/lexicons/chat/bsky/group/getJoinLinkPreviews.defs.js +1 -1
  203. package/dist/lexicons/chat/bsky/group/getJoinLinkPreviews.defs.js.map +1 -1
  204. package/dist/lexicons/chat/bsky/group/listJoinRequests.defs.d.ts +1 -1
  205. package/dist/lexicons/chat/bsky/group/listJoinRequests.defs.d.ts.map +1 -1
  206. package/dist/lexicons/chat/bsky/group/listJoinRequests.defs.js +1 -1
  207. package/dist/lexicons/chat/bsky/group/listJoinRequests.defs.js.map +1 -1
  208. package/dist/lexicons/chat/bsky/group/listMutualGroups.defs.d.ts +1 -1
  209. package/dist/lexicons/chat/bsky/group/listMutualGroups.defs.d.ts.map +1 -1
  210. package/dist/lexicons/chat/bsky/group/listMutualGroups.defs.js +1 -1
  211. package/dist/lexicons/chat/bsky/group/listMutualGroups.defs.js.map +1 -1
  212. package/dist/lexicons/chat/bsky/group/rejectJoinRequest.defs.d.ts +1 -1
  213. package/dist/lexicons/chat/bsky/group/rejectJoinRequest.defs.d.ts.map +1 -1
  214. package/dist/lexicons/chat/bsky/group/rejectJoinRequest.defs.js +1 -1
  215. package/dist/lexicons/chat/bsky/group/rejectJoinRequest.defs.js.map +1 -1
  216. package/dist/lexicons/chat/bsky/group/removeMembers.defs.d.ts +1 -1
  217. package/dist/lexicons/chat/bsky/group/removeMembers.defs.d.ts.map +1 -1
  218. package/dist/lexicons/chat/bsky/group/removeMembers.defs.js +1 -1
  219. package/dist/lexicons/chat/bsky/group/removeMembers.defs.js.map +1 -1
  220. package/dist/lexicons/chat/bsky/group/requestJoin.defs.d.ts +1 -1
  221. package/dist/lexicons/chat/bsky/group/requestJoin.defs.d.ts.map +1 -1
  222. package/dist/lexicons/chat/bsky/group/requestJoin.defs.js +1 -1
  223. package/dist/lexicons/chat/bsky/group/requestJoin.defs.js.map +1 -1
  224. package/dist/lexicons/chat/bsky/group/updateJoinRequestsRead.defs.d.ts +1 -1
  225. package/dist/lexicons/chat/bsky/group/updateJoinRequestsRead.defs.d.ts.map +1 -1
  226. package/dist/lexicons/chat/bsky/group/updateJoinRequestsRead.defs.js +1 -1
  227. package/dist/lexicons/chat/bsky/group/updateJoinRequestsRead.defs.js.map +1 -1
  228. package/dist/lexicons/chat/bsky/group/withdrawJoinRequest.defs.d.ts +1 -1
  229. package/dist/lexicons/chat/bsky/group/withdrawJoinRequest.defs.d.ts.map +1 -1
  230. package/dist/lexicons/chat/bsky/group/withdrawJoinRequest.defs.js +1 -1
  231. package/dist/lexicons/chat/bsky/group/withdrawJoinRequest.defs.js.map +1 -1
  232. package/dist/lexicons/chat/bsky/moderation/defs.defs.d.ts +6 -6
  233. package/dist/lexicons/chat/bsky/moderation/defs.defs.d.ts.map +1 -1
  234. package/dist/lexicons/chat/bsky/moderation/defs.defs.js +3 -3
  235. package/dist/lexicons/chat/bsky/moderation/defs.defs.js.map +1 -1
  236. package/dist/lexicons/chat/bsky/moderation/getConvo.defs.d.ts +1 -1
  237. package/dist/lexicons/chat/bsky/moderation/getConvo.defs.d.ts.map +1 -1
  238. package/dist/lexicons/chat/bsky/moderation/getConvo.defs.js +1 -1
  239. package/dist/lexicons/chat/bsky/moderation/getConvo.defs.js.map +1 -1
  240. package/dist/lexicons/chat/bsky/moderation/getConvoMembers.defs.d.ts +1 -1
  241. package/dist/lexicons/chat/bsky/moderation/getConvoMembers.defs.d.ts.map +1 -1
  242. package/dist/lexicons/chat/bsky/moderation/getConvoMembers.defs.js +1 -1
  243. package/dist/lexicons/chat/bsky/moderation/getConvoMembers.defs.js.map +1 -1
  244. package/dist/lexicons/chat/bsky/moderation/getConvos.defs.d.ts +1 -1
  245. package/dist/lexicons/chat/bsky/moderation/getConvos.defs.d.ts.map +1 -1
  246. package/dist/lexicons/chat/bsky/moderation/getConvos.defs.js +1 -1
  247. package/dist/lexicons/chat/bsky/moderation/getConvos.defs.js.map +1 -1
  248. package/dist/lexicons/chat/bsky/notification/defs.d.ts +2 -0
  249. package/dist/lexicons/chat/bsky/notification/defs.d.ts.map +1 -0
  250. package/dist/lexicons/chat/bsky/notification/defs.defs.d.ts +20 -0
  251. package/dist/lexicons/chat/bsky/notification/defs.defs.d.ts.map +1 -0
  252. package/dist/lexicons/chat/bsky/notification/defs.defs.js +19 -0
  253. package/dist/lexicons/chat/bsky/notification/defs.defs.js.map +1 -0
  254. package/dist/lexicons/chat/bsky/notification/defs.js +5 -0
  255. package/dist/lexicons/chat/bsky/notification/defs.js.map +1 -0
  256. package/dist/lexicons/chat/bsky/notification/getPreferences.d.ts +3 -0
  257. package/dist/lexicons/chat/bsky/notification/getPreferences.d.ts.map +1 -0
  258. package/dist/lexicons/chat/bsky/notification/getPreferences.defs.d.ts +18 -0
  259. package/dist/lexicons/chat/bsky/notification/getPreferences.defs.d.ts.map +1 -0
  260. package/dist/lexicons/chat/bsky/notification/getPreferences.defs.js +16 -0
  261. package/dist/lexicons/chat/bsky/notification/getPreferences.defs.js.map +1 -0
  262. package/dist/lexicons/chat/bsky/notification/getPreferences.js +6 -0
  263. package/dist/lexicons/chat/bsky/notification/getPreferences.js.map +1 -0
  264. package/dist/lexicons/chat/bsky/notification/putPreferences.d.ts +3 -0
  265. package/dist/lexicons/chat/bsky/notification/putPreferences.d.ts.map +1 -0
  266. package/dist/lexicons/chat/bsky/notification/putPreferences.defs.d.ts +27 -0
  267. package/dist/lexicons/chat/bsky/notification/putPreferences.defs.d.ts.map +1 -0
  268. package/dist/lexicons/chat/bsky/notification/putPreferences.defs.js +22 -0
  269. package/dist/lexicons/chat/bsky/notification/putPreferences.defs.js.map +1 -0
  270. package/dist/lexicons/chat/bsky/notification/putPreferences.js +6 -0
  271. package/dist/lexicons/chat/bsky/notification/putPreferences.js.map +1 -0
  272. package/dist/lexicons/chat/bsky/notification.d.ts +4 -0
  273. package/dist/lexicons/chat/bsky/notification.d.ts.map +1 -0
  274. package/dist/lexicons/chat/bsky/notification.js +7 -0
  275. package/dist/lexicons/chat/bsky/notification.js.map +1 -0
  276. package/dist/lexicons/chat/bsky.d.ts +1 -0
  277. package/dist/lexicons/chat/bsky.d.ts.map +1 -1
  278. package/dist/lexicons/chat/bsky.js +1 -0
  279. package/dist/lexicons/chat/bsky.js.map +1 -1
  280. package/dist/lexicons/tools/ozone/report/defs.defs.d.ts +4 -0
  281. package/dist/lexicons/tools/ozone/report/defs.defs.d.ts.map +1 -1
  282. package/dist/lexicons/tools/ozone/report/defs.defs.js +2 -0
  283. package/dist/lexicons/tools/ozone/report/defs.defs.js.map +1 -1
  284. package/dist/lexicons/tools/ozone/report/queryActivities.d.ts +3 -0
  285. package/dist/lexicons/tools/ozone/report/queryActivities.d.ts.map +1 -0
  286. package/dist/lexicons/tools/ozone/report/queryActivities.defs.d.ts +42 -0
  287. package/dist/lexicons/tools/ozone/report/queryActivities.defs.d.ts.map +1 -0
  288. package/dist/lexicons/tools/ozone/report/queryActivities.defs.js +31 -0
  289. package/dist/lexicons/tools/ozone/report/queryActivities.defs.js.map +1 -0
  290. package/dist/lexicons/tools/ozone/report/queryActivities.js +6 -0
  291. package/dist/lexicons/tools/ozone/report/queryActivities.js.map +1 -0
  292. package/dist/lexicons/tools/ozone/report.d.ts +1 -0
  293. package/dist/lexicons/tools/ozone/report.d.ts.map +1 -1
  294. package/dist/lexicons/tools/ozone/report.js +1 -0
  295. package/dist/lexicons/tools/ozone/report.js.map +1 -1
  296. package/dist/proto/bsky_pb.d.ts +51 -55
  297. package/dist/proto/bsky_pb.d.ts.map +1 -1
  298. package/dist/proto/bsky_pb.js +67 -74
  299. package/dist/proto/bsky_pb.js.map +1 -1
  300. package/package.json +9 -9
  301. package/proto/bsky.proto +21 -18
  302. package/src/api/app/bsky/actor/searchActorsTypeahead.ts +5 -3
  303. package/src/api/app/bsky/feed/searchPostsV2.ts +232 -0
  304. package/src/api/app/bsky/notification/putPreferencesV2.ts +4 -1
  305. package/src/api/app/bsky/notification/util.ts +7 -11
  306. package/src/api/blob-dispatcher.ts +12 -8
  307. package/src/api/blob-resolver.ts +0 -1
  308. package/src/api/index.ts +2 -0
  309. package/src/data-plane/bsync/index.ts +12 -10
  310. package/src/data-plane/server/background.ts +49 -18
  311. package/src/data-plane/server/index.ts +12 -10
  312. package/src/data-plane/server/indexing/index.ts +1 -1
  313. package/src/data-plane/server/indexing/plugins/block.ts +4 -1
  314. package/src/data-plane/server/indexing/plugins/chat-declaration.ts +4 -1
  315. package/src/data-plane/server/indexing/plugins/feed-generator.ts +4 -1
  316. package/src/data-plane/server/indexing/plugins/follow.ts +4 -1
  317. package/src/data-plane/server/indexing/plugins/germ-declaration.ts +4 -1
  318. package/src/data-plane/server/indexing/plugins/labeler.ts +4 -1
  319. package/src/data-plane/server/indexing/plugins/like.ts +4 -1
  320. package/src/data-plane/server/indexing/plugins/list-block.ts +4 -1
  321. package/src/data-plane/server/indexing/plugins/list-item.ts +4 -1
  322. package/src/data-plane/server/indexing/plugins/list.ts +4 -1
  323. package/src/data-plane/server/indexing/plugins/notif-declaration.ts +4 -1
  324. package/src/data-plane/server/indexing/plugins/post-gate.ts +4 -1
  325. package/src/data-plane/server/indexing/plugins/post.ts +4 -1
  326. package/src/data-plane/server/indexing/plugins/profile.ts +4 -1
  327. package/src/data-plane/server/indexing/plugins/repost.ts +4 -1
  328. package/src/data-plane/server/indexing/plugins/starter-pack.ts +4 -1
  329. package/src/data-plane/server/indexing/plugins/status.ts +4 -1
  330. package/src/data-plane/server/indexing/plugins/thread-gate.ts +4 -1
  331. package/src/data-plane/server/indexing/plugins/verification.ts +4 -1
  332. package/src/data-plane/server/indexing/processor.ts +1 -1
  333. package/src/data-plane/server/routes/notifs.ts +0 -14
  334. package/src/data-plane/server/routes/search.ts +3 -2
  335. package/src/data-plane/server/subscription.ts +74 -31
  336. package/src/feature-gates/index.ts +10 -6
  337. package/src/feature-gates/metrics.test.ts +12 -12
  338. package/src/feature-gates/metrics.ts +8 -8
  339. package/src/index.ts +16 -9
  340. package/tests/_util.ts +8 -25
  341. package/tests/admin/admin-auth.test.ts +2 -2
  342. package/tests/admin/moderation.test.ts +1 -1
  343. package/tests/auth.test.ts +4 -6
  344. package/tests/blob-resolver.test.ts +4 -5
  345. package/tests/data-plane/db.test.ts +1 -1
  346. package/tests/data-plane/duplicate-records.test.ts +1 -1
  347. package/tests/data-plane/handle-invalidation.test.ts +2 -2
  348. package/tests/data-plane/indexing.test.ts +24 -21
  349. package/tests/data-plane/subscription.test.ts +1 -1
  350. package/tests/data-plane/thread-mutes.test.ts +2 -2
  351. package/tests/entryway-auth.test.ts +4 -5
  352. package/tests/feed-generation.test.ts +5 -5
  353. package/tests/image/server.test.ts +1 -1
  354. package/tests/label-hydration.test.ts +3 -5
  355. package/tests/postgates.test.ts +3 -6
  356. package/tests/query-labels.test.ts +3 -5
  357. package/tests/redis-cache.test.ts +1 -3
  358. package/tests/server.test.ts +11 -16
  359. package/tests/sitemap.test.ts +3 -4
  360. package/tests/stash.test.ts +12 -8
  361. package/tests/utils.test.ts +3 -13
  362. package/tests/views/account-deactivation.test.ts +3 -5
  363. package/tests/views/actor-likes.test.ts +3 -5
  364. package/tests/views/actor-search.test.ts +6 -7
  365. package/tests/views/age-assurance-v2.test.ts +9 -6
  366. package/tests/views/age-assurance.test.ts +30 -36
  367. package/tests/views/author-feed.test.ts +4 -6
  368. package/tests/views/block-lists.test.ts +3 -5
  369. package/tests/views/blocks.test.ts +3 -5
  370. package/tests/views/bookmarks.test.ts +4 -4
  371. package/tests/views/drafts.test.ts +7 -14
  372. package/tests/views/feed-hidden-replies.test.ts +3 -6
  373. package/tests/views/feed-view-post.test.ts +3 -6
  374. package/tests/views/follows.test.ts +4 -6
  375. package/tests/views/get-config.test.ts +4 -7
  376. package/tests/views/get-suggested-onboarding-users.test.ts +11 -9
  377. package/tests/views/get-suggested-starter-packs.test.ts +11 -9
  378. package/tests/views/get-trends.test.ts +15 -9
  379. package/tests/views/internal-actor.test.ts +3 -6
  380. package/tests/views/known-followers.test.ts +3 -6
  381. package/tests/views/labeler-service.test.ts +3 -5
  382. package/tests/views/labels-needs-review.test.ts +3 -6
  383. package/tests/views/labels-takedown.test.ts +3 -4
  384. package/tests/views/likes.test.ts +4 -6
  385. package/tests/views/list-feed.test.ts +3 -5
  386. package/tests/views/lists.test.ts +3 -5
  387. package/tests/views/mute-lists.test.ts +3 -5
  388. package/tests/views/mutes.test.ts +4 -5
  389. package/tests/views/notifications.test.ts +12 -11
  390. package/tests/views/post-search.test.ts +3 -24
  391. package/tests/views/posts-debug.test.ts +11 -6
  392. package/tests/views/posts.test.ts +3 -4
  393. package/tests/views/profile-debug.test.ts +11 -5
  394. package/tests/views/profile.test.ts +11 -5
  395. package/tests/views/quotes.test.ts +4 -6
  396. package/tests/views/reposts.test.ts +4 -6
  397. package/tests/views/starter-packs.test.ts +3 -6
  398. package/tests/views/suggestions.test.ts +9 -13
  399. package/tests/views/thread-v2.test.ts +3 -5
  400. package/tests/views/thread.test.ts +3 -7
  401. package/tests/views/threadgating.test.ts +3 -5
  402. package/tests/views/timeline.test.ts +4 -5
  403. package/tests/views/verification.test.ts +4 -6
  404. package/tsconfig.build.tsbuildinfo +1 -1
  405. package/vitest.config.ts +1 -0
@@ -42,17 +42,17 @@ export class FeatureGatesClient {
42
42
  this.client = new GrowthBookClient({
43
43
  apiHost: this.config.growthBookApiHost,
44
44
  clientKey: this.config.growthBookClientKey,
45
- onFeatureUsage: (feature, result, userContext) => {
45
+ onFeatureUsage: async (feature, result, userContext) => {
46
46
  if (IGNORE_METRICS_FOR_GATES.has(feature))
47
47
  return;
48
- this.metrics.track('feature:viewed', {
48
+ await this.metrics.track('feature:viewed', {
49
49
  featureId: feature,
50
50
  featureResultValue: result.value,
51
51
  experimentId: result.experiment?.key,
52
52
  variationId: result.experimentResult?.key,
53
53
  }, parsedUserContextToTrackingMetadata(extractUserContextFromGrowthbookUserContext(userContext)));
54
54
  },
55
- trackingCallback: (experiment, result, userContext) => {
55
+ trackingCallback: async (experiment, result, userContext) => {
56
56
  /**
57
57
  * Experiments are only fired in a feature gate has an Experiment
58
58
  * attached in Growthbook. Howerver, we want to be extra sure that a
@@ -62,7 +62,7 @@ export class FeatureGatesClient {
62
62
  if (result.featureId &&
63
63
  IGNORE_METRICS_FOR_GATES.has(result.featureId))
64
64
  return;
65
- this.metrics.track('experiment:viewed', {
65
+ await this.metrics.track('experiment:viewed', {
66
66
  experimentId: experiment.key,
67
67
  variationId: result.key,
68
68
  }, parsedUserContextToTrackingMetadata(extractUserContextFromGrowthbookUserContext(userContext)));
@@ -103,14 +103,17 @@ export class FeatureGatesClient {
103
103
  featureGatesLogger.error({ err }, 'Client initialization failed');
104
104
  }
105
105
  }
106
- destroy() {
106
+ async destroy() {
107
107
  if (this.ready) {
108
108
  this.ready = false;
109
109
  if (this.refreshInterval) {
110
110
  clearInterval(this.refreshInterval);
111
111
  }
112
112
  }
113
- this.metrics.stop();
113
+ await this.metrics.stop();
114
+ }
115
+ async [Symbol.asyncDispose]() {
116
+ await this.destroy();
114
117
  }
115
118
  /**
116
119
  * Evaluate multiple feature gates for a given user, returning a map of gate
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/feature-gates/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { GrowthBookClient } from '@growthbook/growthbook'\nimport type express from 'express'\nimport { featureGatesLogger } from '../logger.js'\nimport { Gate, IGNORE_METRICS_FOR_GATES } from './gates.js'\nimport { MetricsClient } from './metrics.js'\nimport {\n CheckedFeatureGatesMap,\n ScopedFeatureGatesClient,\n UserContext,\n} from './types.js'\nimport {\n extractUserContextFromGrowthbookUserContext,\n mergeUserContexts,\n normalizeUserContext,\n parsedUserContextToTrackingMetadata,\n} from './utils.js'\n\n/**\n * We want this to be sufficiently high that we don't time out under\n * normal conditions, but not so high that it takes too long to boot\n * the server.\n */\nconst FETCH_TIMEOUT = 3e3 // 3 seconds\n\n/**\n * StatSig used to default to every 10s, but I think 1m is fine\n */\nconst REFETCH_INTERVAL = 60e3 // 1 minute\n\n/**\n * These need to match what the client sends\n */\nconst ANALYTICS_HEADER_DEVICE_ID = 'X-Bsky-Device-Id'\nconst ANALYTICS_HEADER_SESSION_ID = 'X-Bsky-Session-Id'\n\nexport { type ScopedFeatureGatesClient } from './types.js'\n\nexport class FeatureGatesClient {\n private ready = false\n private client: GrowthBookClient | undefined = undefined\n private refreshInterval: NodeJS.Timeout | undefined = undefined\n private metrics: MetricsClient\n\n /**\n * Easy access to the `Gate` enum for consumers of this class, so they don't\n * need to import it separately.\n */\n Gate = Gate\n\n constructor(\n private config: {\n growthBookApiHost?: string\n growthBookClientKey?: string\n eventProxyTrackingEndpoint?: string\n },\n ) {\n this.metrics = new MetricsClient({\n trackingEndpoint: config.eventProxyTrackingEndpoint,\n })\n }\n\n async start() {\n if (!this.config.growthBookApiHost || !this.config.growthBookClientKey) {\n featureGatesLogger.info(\n {},\n 'feature gates not configured, skipping initialization',\n )\n return\n }\n\n try {\n this.client = new GrowthBookClient({\n apiHost: this.config.growthBookApiHost,\n clientKey: this.config.growthBookClientKey,\n onFeatureUsage: (feature, result, userContext) => {\n if (IGNORE_METRICS_FOR_GATES.has(feature as Gate)) return\n\n this.metrics.track(\n 'feature:viewed',\n {\n featureId: feature,\n featureResultValue: result.value,\n experimentId: result.experiment?.key,\n variationId: result.experimentResult?.key,\n },\n parsedUserContextToTrackingMetadata(\n extractUserContextFromGrowthbookUserContext(userContext),\n ),\n )\n },\n trackingCallback: (experiment, result, userContext) => {\n /**\n * Experiments are only fired in a feature gate has an Experiment\n * attached in Growthbook. Howerver, we want to be extra sure that a\n * misconfigured experiment doesn't result in a huge increase in events, so we\n * protect this here.\n */\n if (\n result.featureId &&\n IGNORE_METRICS_FOR_GATES.has(result.featureId as Gate)\n )\n return\n\n this.metrics.track(\n 'experiment:viewed',\n {\n experimentId: experiment.key,\n variationId: result.key,\n },\n parsedUserContextToTrackingMetadata(\n extractUserContextFromGrowthbookUserContext(userContext),\n ),\n )\n },\n })\n\n const { source, error } = await this.client.init({\n timeout: FETCH_TIMEOUT,\n })\n\n /**\n * This does not necessarily mean that the client completely failed,\n * since it could just be that the request timed out. It may succeed\n * after the timeout, or later during refreshes.\n *\n * @see https://docs.growthbook.io/lib/node#error-handling\n */\n if (error) {\n featureGatesLogger.error(\n { err: error, source },\n 'Client failed to initialize normally',\n )\n }\n\n /**\n * Set up periodic refresh of feature definitions\n *\n * @see https://docs.growthbook.io/lib/node#refreshing-features\n */\n this.refreshInterval = setInterval(async () => {\n try {\n await this.client?.refreshFeatures({\n timeout: FETCH_TIMEOUT,\n })\n } catch (err) {\n featureGatesLogger.error({ err }, 'Failed to refresh features')\n }\n }, REFETCH_INTERVAL)\n\n /* Ready or not, here we come */\n this.ready = true\n } catch (err) {\n featureGatesLogger.error({ err }, 'Client initialization failed')\n }\n }\n\n destroy() {\n if (this.ready) {\n this.ready = false\n if (this.refreshInterval) {\n clearInterval(this.refreshInterval)\n }\n }\n this.metrics.stop()\n }\n\n /**\n * Evaluate multiple feature gates for a given user, returning a map of gate\n * ID to boolean result.\n */\n private checkGates(\n gates: Gate[],\n userContext: UserContext,\n ): CheckedFeatureGatesMap {\n const gb = this.client\n const attributes = normalizeUserContext(userContext)\n if (!gb || !this.ready) return new Map(gates.map((g) => [g, false]))\n return new Map(gates.map((g) => [g, gb.isOn(g, { attributes })]))\n }\n\n scope(scopedUserContext: UserContext): ScopedFeatureGatesClient {\n /*\n * Create initial deviceId and sessionId values for the scoped client, to\n * be used throughout this request lifecycle.\n */\n const base = normalizeUserContext(scopedUserContext)\n return {\n Gate: this.Gate,\n checkGates: (\n gates: Gate[],\n userContextOverrides?: Pick<UserContext, 'did'>,\n ) => {\n const userContext = mergeUserContexts(base, userContextOverrides)\n return this.checkGates(gates, userContext)\n },\n checkGate: (gate: Gate, userContextOverrides?: UserContext) => {\n const userContext = mergeUserContexts(base, userContextOverrides)\n return this.checkGates([gate], userContext).get(gate) || false\n },\n }\n }\n\n /**\n * Parse properties available in XRPC handlers to `UserContext`. The returned\n * proeprties are used as GrowthBook `attributes` as well as the metadata\n * payload for our analytics events. This ensures that the same user properties\n * are used for both feature gate targeting and analytics.\n */\n parseUserContextFromHandler({\n viewer,\n req,\n }: {\n /**\n * The user's DID\n */\n viewer: string | null\n /**\n * The express request object, used to extract analytics headers for the user context\n */\n req: express.Request\n }): UserContext {\n const deviceId = req.header(ANALYTICS_HEADER_DEVICE_ID)\n const sessionId = req.header(ANALYTICS_HEADER_SESSION_ID)\n\n return normalizeUserContext({\n did: viewer,\n deviceId,\n sessionId,\n })\n }\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/feature-gates/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { GrowthBookClient } from '@growthbook/growthbook'\nimport type express from 'express'\nimport { featureGatesLogger } from '../logger.js'\nimport { Gate, IGNORE_METRICS_FOR_GATES } from './gates.js'\nimport { MetricsClient } from './metrics.js'\nimport {\n CheckedFeatureGatesMap,\n ScopedFeatureGatesClient,\n UserContext,\n} from './types.js'\nimport {\n extractUserContextFromGrowthbookUserContext,\n mergeUserContexts,\n normalizeUserContext,\n parsedUserContextToTrackingMetadata,\n} from './utils.js'\n\n/**\n * We want this to be sufficiently high that we don't time out under\n * normal conditions, but not so high that it takes too long to boot\n * the server.\n */\nconst FETCH_TIMEOUT = 3e3 // 3 seconds\n\n/**\n * StatSig used to default to every 10s, but I think 1m is fine\n */\nconst REFETCH_INTERVAL = 60e3 // 1 minute\n\n/**\n * These need to match what the client sends\n */\nconst ANALYTICS_HEADER_DEVICE_ID = 'X-Bsky-Device-Id'\nconst ANALYTICS_HEADER_SESSION_ID = 'X-Bsky-Session-Id'\n\nexport { type ScopedFeatureGatesClient } from './types.js'\n\nexport class FeatureGatesClient {\n private ready = false\n private client: GrowthBookClient | undefined = undefined\n private refreshInterval: NodeJS.Timeout | undefined = undefined\n private metrics: MetricsClient\n\n /**\n * Easy access to the `Gate` enum for consumers of this class, so they don't\n * need to import it separately.\n */\n Gate = Gate\n\n constructor(\n private config: {\n growthBookApiHost?: string\n growthBookClientKey?: string\n eventProxyTrackingEndpoint?: string\n },\n ) {\n this.metrics = new MetricsClient({\n trackingEndpoint: config.eventProxyTrackingEndpoint,\n })\n }\n\n async start() {\n if (!this.config.growthBookApiHost || !this.config.growthBookClientKey) {\n featureGatesLogger.info(\n {},\n 'feature gates not configured, skipping initialization',\n )\n return\n }\n\n try {\n this.client = new GrowthBookClient({\n apiHost: this.config.growthBookApiHost,\n clientKey: this.config.growthBookClientKey,\n onFeatureUsage: async (feature, result, userContext) => {\n if (IGNORE_METRICS_FOR_GATES.has(feature as Gate)) return\n\n await this.metrics.track(\n 'feature:viewed',\n {\n featureId: feature,\n featureResultValue: result.value,\n experimentId: result.experiment?.key,\n variationId: result.experimentResult?.key,\n },\n parsedUserContextToTrackingMetadata(\n extractUserContextFromGrowthbookUserContext(userContext),\n ),\n )\n },\n trackingCallback: async (experiment, result, userContext) => {\n /**\n * Experiments are only fired in a feature gate has an Experiment\n * attached in Growthbook. Howerver, we want to be extra sure that a\n * misconfigured experiment doesn't result in a huge increase in events, so we\n * protect this here.\n */\n if (\n result.featureId &&\n IGNORE_METRICS_FOR_GATES.has(result.featureId as Gate)\n )\n return\n\n await this.metrics.track(\n 'experiment:viewed',\n {\n experimentId: experiment.key,\n variationId: result.key,\n },\n parsedUserContextToTrackingMetadata(\n extractUserContextFromGrowthbookUserContext(userContext),\n ),\n )\n },\n })\n\n const { source, error } = await this.client.init({\n timeout: FETCH_TIMEOUT,\n })\n\n /**\n * This does not necessarily mean that the client completely failed,\n * since it could just be that the request timed out. It may succeed\n * after the timeout, or later during refreshes.\n *\n * @see https://docs.growthbook.io/lib/node#error-handling\n */\n if (error) {\n featureGatesLogger.error(\n { err: error, source },\n 'Client failed to initialize normally',\n )\n }\n\n /**\n * Set up periodic refresh of feature definitions\n *\n * @see https://docs.growthbook.io/lib/node#refreshing-features\n */\n this.refreshInterval = setInterval(async () => {\n try {\n await this.client?.refreshFeatures({\n timeout: FETCH_TIMEOUT,\n })\n } catch (err) {\n featureGatesLogger.error({ err }, 'Failed to refresh features')\n }\n }, REFETCH_INTERVAL)\n\n /* Ready or not, here we come */\n this.ready = true\n } catch (err) {\n featureGatesLogger.error({ err }, 'Client initialization failed')\n }\n }\n\n async destroy() {\n if (this.ready) {\n this.ready = false\n if (this.refreshInterval) {\n clearInterval(this.refreshInterval)\n }\n }\n await this.metrics.stop()\n }\n\n async [Symbol.asyncDispose]() {\n await this.destroy()\n }\n\n /**\n * Evaluate multiple feature gates for a given user, returning a map of gate\n * ID to boolean result.\n */\n private checkGates(\n gates: Gate[],\n userContext: UserContext,\n ): CheckedFeatureGatesMap {\n const gb = this.client\n const attributes = normalizeUserContext(userContext)\n if (!gb || !this.ready) return new Map(gates.map((g) => [g, false]))\n return new Map(gates.map((g) => [g, gb.isOn(g, { attributes })]))\n }\n\n scope(scopedUserContext: UserContext): ScopedFeatureGatesClient {\n /*\n * Create initial deviceId and sessionId values for the scoped client, to\n * be used throughout this request lifecycle.\n */\n const base = normalizeUserContext(scopedUserContext)\n return {\n Gate: this.Gate,\n checkGates: (\n gates: Gate[],\n userContextOverrides?: Pick<UserContext, 'did'>,\n ) => {\n const userContext = mergeUserContexts(base, userContextOverrides)\n return this.checkGates(gates, userContext)\n },\n checkGate: (gate: Gate, userContextOverrides?: UserContext) => {\n const userContext = mergeUserContexts(base, userContextOverrides)\n return this.checkGates([gate], userContext).get(gate) || false\n },\n }\n }\n\n /**\n * Parse properties available in XRPC handlers to `UserContext`. The returned\n * proeprties are used as GrowthBook `attributes` as well as the metadata\n * payload for our analytics events. This ensures that the same user properties\n * are used for both feature gate targeting and analytics.\n */\n parseUserContextFromHandler({\n viewer,\n req,\n }: {\n /**\n * The user's DID\n */\n viewer: string | null\n /**\n * The express request object, used to extract analytics headers for the user context\n */\n req: express.Request\n }): UserContext {\n const deviceId = req.header(ANALYTICS_HEADER_DEVICE_ID)\n const sessionId = req.header(ANALYTICS_HEADER_SESSION_ID)\n\n return normalizeUserContext({\n did: viewer,\n deviceId,\n sessionId,\n })\n }\n}\n"]}
@@ -23,9 +23,9 @@ export declare class MetricsClient<M extends Record<string, any> = Events> {
23
23
  private flushInterval;
24
24
  constructor(config: Config);
25
25
  start(): void;
26
- stop(): void;
27
- track<E extends keyof M>(event: E, payload: M[E], metadata?: Record<string, any>): void;
28
- flush(): void;
26
+ stop(): Promise<void>;
27
+ track<E extends keyof M>(event: E, payload: M[E], metadata?: Record<string, any>): Promise<void>;
28
+ flush(): Promise<void>;
29
29
  private sendBatch;
30
30
  }
31
31
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../../src/feature-gates/metrics.ts"],"names":[],"mappings":"AAEA,KAAK,MAAM,GAAG;IACZ,mBAAmB,EAAE;QACnB,YAAY,EAAE,MAAM,CAAA;QACpB,WAAW,EAAE,MAAM,CAAA;KACpB,CAAA;IACD,gBAAgB,EAAE;QAChB,SAAS,EAAE,MAAM,CAAA;QACjB,kBAAkB,EAAE,OAAO,CAAA;QAC3B,6DAA6D;QAC7D,YAAY,CAAC,EAAE,MAAM,CAAA;QACrB,6DAA6D;QAC7D,WAAW,CAAC,EAAE,MAAM,CAAA;KACrB,CAAA;CACF,CAAA;AASD,MAAM,MAAM,MAAM,GAAG;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAC1B,CAAA;AAED,qBAAa,aAAa,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM;IAMnD,OAAO,CAAC,MAAM;IAL1B,YAAY,SAAM;IAElB,OAAO,CAAC,OAAO,CAAiB;IAChC,OAAO,CAAC,KAAK,CAAiB;IAC9B,OAAO,CAAC,aAAa,CAA8B;IACnD,YAAoB,MAAM,EAAE,MAAM,EAAI;IAEtC,KAAK,SAMJ;IAED,IAAI,SAMH;IAED,KAAK,CAAC,CAAC,SAAS,MAAM,CAAC,EACrB,KAAK,EAAE,CAAC,EACR,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,EACb,QAAQ,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,QAgBnC;IAED,KAAK,SAIJ;YAEa,SAAS;CA2BxB"}
1
+ {"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../../src/feature-gates/metrics.ts"],"names":[],"mappings":"AAEA,KAAK,MAAM,GAAG;IACZ,mBAAmB,EAAE;QACnB,YAAY,EAAE,MAAM,CAAA;QACpB,WAAW,EAAE,MAAM,CAAA;KACpB,CAAA;IACD,gBAAgB,EAAE;QAChB,SAAS,EAAE,MAAM,CAAA;QACjB,kBAAkB,EAAE,OAAO,CAAA;QAC3B,6DAA6D;QAC7D,YAAY,CAAC,EAAE,MAAM,CAAA;QACrB,6DAA6D;QAC7D,WAAW,CAAC,EAAE,MAAM,CAAA;KACrB,CAAA;CACF,CAAA;AASD,MAAM,MAAM,MAAM,GAAG;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAC1B,CAAA;AAED,qBAAa,aAAa,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM;IAMnD,OAAO,CAAC,MAAM;IAL1B,YAAY,SAAM;IAElB,OAAO,CAAC,OAAO,CAAiB;IAChC,OAAO,CAAC,KAAK,CAAiB;IAC9B,OAAO,CAAC,aAAa,CAA8B;IACnD,YAAoB,MAAM,EAAE,MAAM,EAAI;IAEtC,KAAK,SAMJ;IAEK,IAAI,kBAMT;IAEK,KAAK,CAAC,CAAC,SAAS,MAAM,CAAC,EAC3B,KAAK,EAAE,CAAC,EACR,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,EACb,QAAQ,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,iBAgBnC;IAEK,KAAK,kBAIV;YAEa,SAAS;CA2BxB"}
@@ -12,18 +12,18 @@ export class MetricsClient {
12
12
  return;
13
13
  this.started = true;
14
14
  this.flushInterval = setInterval(() => {
15
- this.flush();
15
+ void this.flush();
16
16
  }, 10_000);
17
17
  }
18
- stop() {
18
+ async stop() {
19
19
  if (this.flushInterval) {
20
20
  clearInterval(this.flushInterval);
21
21
  this.flushInterval = null;
22
22
  }
23
- this.flush();
23
+ await this.flush();
24
24
  }
25
- track(event, payload, metadata = {}) {
26
- this.start();
25
+ async track(event, payload, metadata = {}) {
26
+ await this.start();
27
27
  const e = {
28
28
  source: 'appview',
29
29
  time: Date.now(),
@@ -33,14 +33,14 @@ export class MetricsClient {
33
33
  };
34
34
  this.queue.push(e);
35
35
  if (this.queue.length > this.maxBatchSize) {
36
- this.flush();
36
+ await this.flush();
37
37
  }
38
38
  }
39
- flush() {
39
+ async flush() {
40
40
  if (!this.queue.length)
41
41
  return;
42
42
  const events = this.queue.splice(0, this.queue.length);
43
- this.sendBatch(events);
43
+ await this.sendBatch(events);
44
44
  }
45
45
  async sendBatch(events) {
46
46
  if (!this.config.trackingEndpoint)
@@ -1 +1 @@
1
- {"version":3,"file":"metrics.js","sourceRoot":"","sources":["../../src/feature-gates/metrics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAA;AA4BjD,MAAM,OAAO,aAAa;IAMxB,YAAoB,MAAc;QAAd,WAAM,GAAN,MAAM,CAAQ;QALlC,iBAAY,GAAG,GAAG,CAAA;QAEV,YAAO,GAAY,KAAK,CAAA;QACxB,UAAK,GAAe,EAAE,CAAA;QACtB,kBAAa,GAA0B,IAAI,CAAA;IACd,CAAC;IAEtC,KAAK;QACH,IAAI,IAAI,CAAC,OAAO;YAAE,OAAM;QACxB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAA;QACnB,IAAI,CAAC,aAAa,GAAG,WAAW,CAAC,GAAG,EAAE;YACpC,IAAI,CAAC,KAAK,EAAE,CAAA;QACd,CAAC,EAAE,MAAM,CAAC,CAAA;IACZ,CAAC;IAED,IAAI;QACF,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACvB,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC,CAAA;YACjC,IAAI,CAAC,aAAa,GAAG,IAAI,CAAA;QAC3B,CAAC;QACD,IAAI,CAAC,KAAK,EAAE,CAAA;IACd,CAAC;IAED,KAAK,CACH,KAAQ,EACR,OAAa,EACb,QAAQ,GAAwB,EAAE;QAElC,IAAI,CAAC,KAAK,EAAE,CAAA;QAEZ,MAAM,CAAC,GAAG;YACR,MAAM,EAAE,SAAS;YACjB,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE;YAChB,KAAK;YACL,OAAO;YACP,QAAQ;SACT,CAAA;QACD,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QAElB,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;YAC1C,IAAI,CAAC,KAAK,EAAE,CAAA;QACd,CAAC;IACH,CAAC;IAED,KAAK;QACH,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM;YAAE,OAAM;QAC9B,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;QACtD,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAA;IACxB,CAAC;IAEO,KAAK,CAAC,SAAS,CAAC,MAAkB;QACxC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,gBAAgB;YAAE,OAAM;QAEzC,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,gBAAgB,EAAE;gBACpD,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE;oBACP,cAAc,EAAE,kBAAkB;iBACnC;gBACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;gBAChC,SAAS,EAAE,IAAI;aAChB,CAAC,CAAA;YAEF,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;gBACZ,MAAM,SAAS,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,eAAe,CAAC,CAAA;gBAC/D,kBAAkB,CAAC,KAAK,CACtB,EAAE,GAAG,EAAE,IAAI,KAAK,CAAC,GAAG,GAAG,CAAC,MAAM,sBAAsB,SAAS,EAAE,CAAC,EAAE,EAClE,wBAAwB,CACzB,CAAA;YACH,CAAC;iBAAM,CAAC;gBACN,iDAAiD;gBACjD,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;YAClC,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,kBAAkB,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,EAAE,wBAAwB,CAAC,CAAA;QAC7D,CAAC;IACH,CAAC;CACF","sourcesContent":["import { featureGatesLogger } from '../logger.js'\n\ntype Events = {\n 'experiment:viewed': {\n experimentId: string\n variationId: string\n }\n 'feature:viewed': {\n featureId: string\n featureResultValue: unknown\n /** Only available if feature has experiment rules applied */\n experimentId?: string\n /** Only available if feature has experiment rules applied */\n variationId?: string\n }\n}\n\ntype Event<M extends Record<string, any>> = {\n time: number\n event: keyof M\n payload: M[keyof M]\n metadata: Record<string, any>\n}\n\nexport type Config = {\n trackingEndpoint?: string\n}\n\nexport class MetricsClient<M extends Record<string, any> = Events> {\n maxBatchSize = 100\n\n private started: boolean = false\n private queue: Event<M>[] = []\n private flushInterval: NodeJS.Timeout | null = null\n constructor(private config: Config) {}\n\n start() {\n if (this.started) return\n this.started = true\n this.flushInterval = setInterval(() => {\n this.flush()\n }, 10_000)\n }\n\n stop() {\n if (this.flushInterval) {\n clearInterval(this.flushInterval)\n this.flushInterval = null\n }\n this.flush()\n }\n\n track<E extends keyof M>(\n event: E,\n payload: M[E],\n metadata: Record<string, any> = {},\n ) {\n this.start()\n\n const e = {\n source: 'appview',\n time: Date.now(),\n event,\n payload,\n metadata,\n }\n this.queue.push(e)\n\n if (this.queue.length > this.maxBatchSize) {\n this.flush()\n }\n }\n\n flush() {\n if (!this.queue.length) return\n const events = this.queue.splice(0, this.queue.length)\n this.sendBatch(events)\n }\n\n private async sendBatch(events: Event<M>[]) {\n if (!this.config.trackingEndpoint) return\n\n try {\n const res = await fetch(this.config.trackingEndpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ events }),\n keepalive: true,\n })\n\n if (!res.ok) {\n const errorText = await res.text().catch(() => 'Unknown error')\n featureGatesLogger.error(\n { err: new Error(`${res.status} Failed to fetch - ${errorText}`) },\n 'Failed to send metrics',\n )\n } else {\n // Drain response body to allow connection reuse.\n await res.text().catch(() => {})\n }\n } catch (err) {\n featureGatesLogger.error({ err }, 'Failed to send metrics')\n }\n }\n}\n"]}
1
+ {"version":3,"file":"metrics.js","sourceRoot":"","sources":["../../src/feature-gates/metrics.ts"],"names":[],"mappings":"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","sourcesContent":["import { featureGatesLogger } from '../logger.js'\n\ntype Events = {\n 'experiment:viewed': {\n experimentId: string\n variationId: string\n }\n 'feature:viewed': {\n featureId: string\n featureResultValue: unknown\n /** Only available if feature has experiment rules applied */\n experimentId?: string\n /** Only available if feature has experiment rules applied */\n variationId?: string\n }\n}\n\ntype Event<M extends Record<string, any>> = {\n time: number\n event: keyof M\n payload: M[keyof M]\n metadata: Record<string, any>\n}\n\nexport type Config = {\n trackingEndpoint?: string\n}\n\nexport class MetricsClient<M extends Record<string, any> = Events> {\n maxBatchSize = 100\n\n private started: boolean = false\n private queue: Event<M>[] = []\n private flushInterval: NodeJS.Timeout | null = null\n constructor(private config: Config) {}\n\n start() {\n if (this.started) return\n this.started = true\n this.flushInterval = setInterval(() => {\n void this.flush()\n }, 10_000)\n }\n\n async stop() {\n if (this.flushInterval) {\n clearInterval(this.flushInterval)\n this.flushInterval = null\n }\n await this.flush()\n }\n\n async track<E extends keyof M>(\n event: E,\n payload: M[E],\n metadata: Record<string, any> = {},\n ) {\n await this.start()\n\n const e = {\n source: 'appview',\n time: Date.now(),\n event,\n payload,\n metadata,\n }\n this.queue.push(e)\n\n if (this.queue.length > this.maxBatchSize) {\n await this.flush()\n }\n }\n\n async flush() {\n if (!this.queue.length) return\n const events = this.queue.splice(0, this.queue.length)\n await this.sendBatch(events)\n }\n\n private async sendBatch(events: Event<M>[]) {\n if (!this.config.trackingEndpoint) return\n\n try {\n const res = await fetch(this.config.trackingEndpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ events }),\n keepalive: true,\n })\n\n if (!res.ok) {\n const errorText = await res.text().catch(() => 'Unknown error')\n featureGatesLogger.error(\n { err: new Error(`${res.status} Failed to fetch - ${errorText}`) },\n 'Failed to send metrics',\n )\n } else {\n // Drain response body to allow connection reuse.\n await res.text().catch(() => {})\n }\n } catch (err) {\n featureGatesLogger.error({ err }, 'Failed to send metrics')\n }\n }\n}\n"]}
package/dist/index.d.ts CHANGED
@@ -25,6 +25,7 @@ export declare class BskyAppView {
25
25
  }): BskyAppView;
26
26
  start(): Promise<http.Server>;
27
27
  destroy(): Promise<void>;
28
+ [Symbol.asyncDispose](): Promise<void>;
28
29
  }
29
30
  export default BskyAppView;
30
31
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,IAAI,MAAM,WAAW,CAAA;AAK5B,OAAO,OAAO,MAAM,SAAS,CAAA;AAO7B,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAczC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAyBzC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1C,YAAY,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AACzC,cAAc,uBAAuB,CAAA;AACrC,OAAO,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAA;AACnE,OAAO,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAA;AAC1D,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAElC,qBAAa,WAAW;IACf,GAAG,EAAE,UAAU,CAAA;IACf,GAAG,EAAE,OAAO,CAAC,WAAW,CAAA;IACxB,MAAM,CAAC,EAAE,IAAI,CAAC,MAAM,CAAA;IAC3B,OAAO,CAAC,UAAU,CAAC,CAAgB;IAEnC,YAAY,IAAI,EAAE;QAAE,GAAG,EAAE,UAAU,CAAC;QAAC,GAAG,EAAE,OAAO,CAAC,WAAW,CAAA;KAAE,EAG9D;IAED,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE;QAClB,MAAM,EAAE,YAAY,CAAA;QACpB,UAAU,EAAE,OAAO,CAAA;KACpB,GAAG,WAAW,CA6Md;IAEK,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAalC;IAEK,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAI7B;CACF;eAEc,WAAW"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,IAAI,MAAM,WAAW,CAAA;AAK5B,OAAO,OAAO,MAAM,SAAS,CAAA;AAI7B,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAczC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAyBzC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1C,YAAY,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AACzC,cAAc,uBAAuB,CAAA;AACrC,OAAO,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAA;AACnE,OAAO,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAA;AAC1D,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAElC,qBAAa,WAAW;IACf,GAAG,EAAE,UAAU,CAAA;IACf,GAAG,EAAE,OAAO,CAAC,WAAW,CAAA;IACxB,MAAM,CAAC,EAAE,IAAI,CAAC,MAAM,CAAA;IAC3B,OAAO,CAAC,UAAU,CAAC,CAA+B;IAElD,YAAY,IAAI,EAAE;QAAE,GAAG,EAAE,UAAU,CAAC;QAAC,GAAG,EAAE,OAAO,CAAC,WAAW,CAAA;KAAE,EAG9D;IAED,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE;QAClB,MAAM,EAAE,YAAY,CAAA;QACpB,UAAU,EAAE,OAAO,CAAA;KACpB,GAAG,WAAW,CA6Md;IAEK,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAalC;IAEK,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAU7B;IAEK,CAAC,MAAM,CAAC,YAAY,CAAC,kBAE1B;CACF;eAEc,WAAW"}
package/dist/index.js CHANGED
@@ -3,10 +3,8 @@ import compression from 'compression';
3
3
  import cors from 'cors';
4
4
  import { Etcd3 } from 'etcd3';
5
5
  import express from 'express';
6
- // eslint-disable-next-line import/default, import/no-named-as-default-member
6
+ // eslint-disable-next-line import/default
7
7
  import httpTerminator from 'http-terminator';
8
- // eslint-disable-next-line import/no-named-as-default-member
9
- const { createHttpTerminator } = httpTerminator;
10
8
  import { DAY, SECOND } from '@atproto/common';
11
9
  import { IdResolver } from '@atproto/identity';
12
10
  import { Client } from '@atproto/lex';
@@ -214,16 +212,27 @@ export class BskyAppView {
214
212
  const server = this.app.listen(this.ctx.cfg.port);
215
213
  this.server = server;
216
214
  server.keepAliveTimeout = 90000;
217
- this.terminator = createHttpTerminator({ server });
215
+ this.terminator = httpTerminator.createHttpTerminator({ server });
218
216
  await events.once(server, 'listening');
219
217
  const { port } = server.address();
220
218
  this.ctx.cfg.assignPort(port);
221
219
  return server;
222
220
  }
223
221
  async destroy() {
224
- this.ctx.featureGatesClient.destroy();
225
- await this.terminator?.terminate();
226
- await this.ctx.etcd?.close();
222
+ try {
223
+ await this.ctx.featureGatesClient.destroy();
224
+ }
225
+ finally {
226
+ try {
227
+ await this.terminator?.terminate();
228
+ }
229
+ finally {
230
+ await this.ctx.etcd?.close();
231
+ }
232
+ }
233
+ }
234
+ async [Symbol.asyncDispose]() {
235
+ await this.destroy();
227
236
  }
228
237
  }
229
238
  export default BskyAppView;
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import events from 'node:events'\nimport http from 'node:http'\nimport { AddressInfo } from 'node:net'\nimport compression from 'compression'\nimport cors from 'cors'\nimport { Etcd3 } from 'etcd3'\nimport express from 'express'\n// eslint-disable-next-line import/default, import/no-named-as-default-member\nimport httpTerminator from 'http-terminator'\n// eslint-disable-next-line import/no-named-as-default-member\nconst { createHttpTerminator } = httpTerminator\ntype HttpTerminator = ReturnType<typeof createHttpTerminator>\nimport { DAY, SECOND } from '@atproto/common'\nimport { Keypair } from '@atproto/crypto'\nimport { IdResolver } from '@atproto/identity'\nimport { Client } from '@atproto/lex'\nimport { createServer } from '@atproto/xrpc-server'\nimport { createBlobDispatcher } from './api/blob-dispatcher.js'\nimport API, {\n blobResolver,\n external,\n health,\n sitemap,\n wellKnown,\n} from './api/index.js'\nimport { AuthVerifier, createPublicKeyObject } from './auth-verifier.js'\nimport { authWithApiKey as bsyncAuth, createBsyncClient } from './bsync.js'\nimport { ServerConfig } from './config.js'\nimport { AppContext } from './context.js'\nimport {\n authWithApiKey as courierAuth,\n createCourierClient,\n} from './courier.js'\nimport {\n BasicHostList,\n EtcdHostList,\n createDataPlaneClient,\n} from './data-plane/client/index.js'\nimport * as error from './error.js'\nimport { FeatureGatesClient } from './feature-gates/index.js'\nimport { Hydrator } from './hydration/hydrator.js'\nimport * as imageServer from './image/server.js'\nimport { ImageUriBuilder } from './image/uri.js'\nimport { createKwsClient } from './kws.js'\nimport { loggerMiddleware } from './logger.js'\nimport {\n authWithApiKey as rolodexAuth,\n createRolodexClient,\n} from './rolodex.js'\nimport { createStashClient } from './stash.js'\nimport { Views } from './views/index.js'\nimport { VideoUriBuilder } from './views/util.js'\n\nexport { ServerConfig } from './config.js'\nexport type { ServerConfigValues } from './config.js'\nexport { AppContext } from './context.js'\nexport * from './data-plane/index.js'\nexport { BackgroundQueue } from './data-plane/server/background.js'\nexport { Database } from './data-plane/server/db/index.js'\nexport { Redis } from './redis.js'\n\nexport class BskyAppView {\n public ctx: AppContext\n public app: express.Application\n public server?: http.Server\n private terminator?: HttpTerminator\n\n constructor(opts: { ctx: AppContext; app: express.Application }) {\n this.ctx = opts.ctx\n this.app = opts.app\n }\n\n static create(opts: {\n config: ServerConfig\n signingKey: Keypair\n }): BskyAppView {\n const { config, signingKey } = opts\n const app = express()\n app.set('trust proxy', true)\n app.use(cors({ maxAge: DAY / SECOND }))\n app.use(loggerMiddleware)\n app.use(compression())\n\n // used solely for handle resolution: identity lookups occur on dataplane\n const idResolver = new IdResolver({\n plcUrl: config.didPlcUrl,\n backupNameservers: config.handleResolveNameservers,\n })\n\n const imgUriBuilderUrl =\n config.cdnUrl ||\n (config.publicUrl ? `${config.publicUrl}/img` : undefined)\n if (!imgUriBuilderUrl) {\n throw new Error('No image URI builder URL could be determined')\n }\n const imgUriBuilder = new ImageUriBuilder(imgUriBuilderUrl)\n const videoUriBuilder = new VideoUriBuilder({\n playlistUrlPattern:\n config.videoPlaylistUrlPattern ||\n `${config.publicUrl}/vid/%s/%s/playlist.m3u8`,\n thumbnailUrlPattern:\n config.videoThumbnailUrlPattern ||\n `${config.publicUrl}/vid/%s/%s/thumbnail.jpg`,\n })\n\n const searchClient = config.searchUrl\n ? new Client(\n {\n service: config.searchUrl,\n },\n {\n // Trust internal services to send us well-formed responses\n strictResponseProcessing: false,\n validateResponse: config.debugMode,\n },\n )\n : undefined\n\n const suggestionsClient = config.suggestionsUrl\n ? new Client(\n {\n service: config.suggestionsUrl,\n headers: config.suggestionsApiKey\n ? { authorization: `Bearer ${config.suggestionsApiKey}` }\n : undefined,\n },\n {\n // Trust internal services to send us well-formed responses\n strictResponseProcessing: false,\n validateResponse: config.debugMode,\n },\n )\n : undefined\n\n const topicsClient = config.topicsUrl\n ? new Client(\n {\n service: config.topicsUrl,\n headers: config.topicsApiKey\n ? { authorization: `Bearer ${config.topicsApiKey}` }\n : undefined,\n },\n {\n // Trust internal services to send us well-formed responses\n strictResponseProcessing: false,\n validateResponse: config.debugMode,\n },\n )\n : undefined\n\n const etcd = config.etcdHosts.length\n ? new Etcd3({ hosts: config.etcdHosts })\n : undefined\n\n const dataplaneHostList =\n etcd && config.dataplaneUrlsEtcdKeyPrefix\n ? new EtcdHostList(\n etcd,\n config.dataplaneUrlsEtcdKeyPrefix,\n config.dataplaneUrls,\n )\n : new BasicHostList(config.dataplaneUrls)\n\n const featureGatesClient = new FeatureGatesClient({\n growthBookApiHost: config.growthBookApiHost,\n growthBookClientKey: config.growthBookClientKey,\n eventProxyTrackingEndpoint: config.eventProxyTrackingEndpoint,\n })\n\n const dataplane = createDataPlaneClient(dataplaneHostList, {\n httpVersion: config.dataplaneHttpVersion,\n rejectUnauthorized: !config.dataplaneIgnoreBadTls,\n })\n const hydrator = new Hydrator(dataplane, config.labelsFromIssuerDids, {\n debugFieldAllowedDids: config.debugFieldAllowedDids,\n featureGatesClient,\n })\n const views = new Views({\n imgUriBuilder: imgUriBuilder,\n videoUriBuilder: videoUriBuilder,\n indexedAtEpoch: config.indexedAtEpoch,\n threadTagsBumpDown: [...config.threadTagsBumpDown],\n threadTagsHide: [...config.threadTagsHide],\n visibilityTagHide: config.visibilityTagHide,\n visibilityTagRankPrefix: config.visibilityTagRankPrefix,\n })\n\n const bsyncClient = createBsyncClient({\n baseUrl: config.bsyncUrl,\n httpVersion: config.bsyncHttpVersion ?? '2',\n nodeOptions: { rejectUnauthorized: !config.bsyncIgnoreBadTls },\n interceptors: config.bsyncApiKey ? [bsyncAuth(config.bsyncApiKey)] : [],\n })\n\n const stashClient = createStashClient(bsyncClient)\n\n const courierClient = config.courierUrl\n ? createCourierClient({\n baseUrl: config.courierUrl,\n httpVersion: config.courierHttpVersion ?? '2',\n nodeOptions: { rejectUnauthorized: !config.courierIgnoreBadTls },\n interceptors: config.courierApiKey\n ? [courierAuth(config.courierApiKey)]\n : [],\n })\n : undefined\n\n const rolodexClient = config.rolodexUrl\n ? createRolodexClient({\n baseUrl: config.rolodexUrl,\n httpVersion: config.rolodexHttpVersion ?? '2',\n nodeOptions: { rejectUnauthorized: !config.rolodexIgnoreBadTls },\n interceptors: config.rolodexApiKey\n ? [rolodexAuth(config.rolodexApiKey)]\n : [],\n })\n : undefined\n\n const kwsClient = config.kws ? createKwsClient(config.kws) : undefined\n\n const entrywayJwtPublicKey = config.entrywayJwtPublicKeyHex\n ? createPublicKeyObject(config.entrywayJwtPublicKeyHex)\n : undefined\n const authVerifier = new AuthVerifier(dataplane, {\n ownDid: config.serverDid,\n alternateAudienceDids: config.alternateAudienceDids,\n modServiceDid: config.modServiceDid,\n adminPasses: config.adminPasswords,\n entrywayJwtPublicKey,\n })\n\n const blobDispatcher = createBlobDispatcher(config)\n\n const ctx = new AppContext({\n cfg: config,\n etcd,\n dataplane,\n dataplaneHostList,\n searchClient,\n suggestionsClient,\n topicsClient,\n hydrator,\n views,\n signingKey,\n idResolver,\n bsyncClient,\n stashClient,\n courierClient,\n rolodexClient,\n authVerifier,\n featureGatesClient,\n blobDispatcher,\n kwsClient,\n })\n\n const server = createServer([], {\n validateResponse: config.debugMode,\n payload: {\n jsonLimit: 100 * 1024, // 100kb\n textLimit: 100 * 1024, // 100kb\n blobLimit: 5 * 1024 * 1024, // 5mb\n },\n })\n\n API(server, ctx)\n\n app.use(health.createRouter(ctx))\n app.use(wellKnown.createRouter(ctx))\n app.use(blobResolver.createMiddleware(ctx))\n app.use(imageServer.createMiddleware(ctx, { prefix: '/img/' }))\n\n if (config.dataplaneUrls.length > 0 || config.dataplaneUrlsEtcdKeyPrefix) {\n app.use(sitemap.createRouter(ctx))\n }\n\n app.use(server.router)\n app.use(error.handler)\n app.use('/external', external.createRouter(ctx))\n\n return new BskyAppView({ ctx, app })\n }\n\n async start(): Promise<http.Server> {\n if (this.ctx.dataplaneHostList instanceof EtcdHostList) {\n await this.ctx.dataplaneHostList.connect()\n }\n this.ctx.featureGatesClient.start() // lazy, no await\n const server = this.app.listen(this.ctx.cfg.port)\n this.server = server\n server.keepAliveTimeout = 90000\n this.terminator = createHttpTerminator({ server })\n await events.once(server, 'listening')\n const { port } = server.address() as AddressInfo\n this.ctx.cfg.assignPort(port)\n return server\n }\n\n async destroy(): Promise<void> {\n this.ctx.featureGatesClient.destroy()\n await this.terminator?.terminate()\n await this.ctx.etcd?.close()\n }\n}\n\nexport default BskyAppView\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import events from 'node:events'\nimport http from 'node:http'\nimport { AddressInfo } from 'node:net'\nimport compression from 'compression'\nimport cors from 'cors'\nimport { Etcd3 } from 'etcd3'\nimport express from 'express'\n// eslint-disable-next-line import/default\nimport httpTerminator from 'http-terminator'\nimport { DAY, SECOND } from '@atproto/common'\nimport { Keypair } from '@atproto/crypto'\nimport { IdResolver } from '@atproto/identity'\nimport { Client } from '@atproto/lex'\nimport { createServer } from '@atproto/xrpc-server'\nimport { createBlobDispatcher } from './api/blob-dispatcher.js'\nimport API, {\n blobResolver,\n external,\n health,\n sitemap,\n wellKnown,\n} from './api/index.js'\nimport { AuthVerifier, createPublicKeyObject } from './auth-verifier.js'\nimport { authWithApiKey as bsyncAuth, createBsyncClient } from './bsync.js'\nimport { ServerConfig } from './config.js'\nimport { AppContext } from './context.js'\nimport {\n authWithApiKey as courierAuth,\n createCourierClient,\n} from './courier.js'\nimport {\n BasicHostList,\n EtcdHostList,\n createDataPlaneClient,\n} from './data-plane/client/index.js'\nimport * as error from './error.js'\nimport { FeatureGatesClient } from './feature-gates/index.js'\nimport { Hydrator } from './hydration/hydrator.js'\nimport * as imageServer from './image/server.js'\nimport { ImageUriBuilder } from './image/uri.js'\nimport { createKwsClient } from './kws.js'\nimport { loggerMiddleware } from './logger.js'\nimport {\n authWithApiKey as rolodexAuth,\n createRolodexClient,\n} from './rolodex.js'\nimport { createStashClient } from './stash.js'\nimport { Views } from './views/index.js'\nimport { VideoUriBuilder } from './views/util.js'\n\nexport { ServerConfig } from './config.js'\nexport type { ServerConfigValues } from './config.js'\nexport { AppContext } from './context.js'\nexport * from './data-plane/index.js'\nexport { BackgroundQueue } from './data-plane/server/background.js'\nexport { Database } from './data-plane/server/db/index.js'\nexport { Redis } from './redis.js'\n\nexport class BskyAppView {\n public ctx: AppContext\n public app: express.Application\n public server?: http.Server\n private terminator?: httpTerminator.HttpTerminator\n\n constructor(opts: { ctx: AppContext; app: express.Application }) {\n this.ctx = opts.ctx\n this.app = opts.app\n }\n\n static create(opts: {\n config: ServerConfig\n signingKey: Keypair\n }): BskyAppView {\n const { config, signingKey } = opts\n const app = express()\n app.set('trust proxy', true)\n app.use(cors({ maxAge: DAY / SECOND }))\n app.use(loggerMiddleware)\n app.use(compression())\n\n // used solely for handle resolution: identity lookups occur on dataplane\n const idResolver = new IdResolver({\n plcUrl: config.didPlcUrl,\n backupNameservers: config.handleResolveNameservers,\n })\n\n const imgUriBuilderUrl =\n config.cdnUrl ||\n (config.publicUrl ? `${config.publicUrl}/img` : undefined)\n if (!imgUriBuilderUrl) {\n throw new Error('No image URI builder URL could be determined')\n }\n const imgUriBuilder = new ImageUriBuilder(imgUriBuilderUrl)\n const videoUriBuilder = new VideoUriBuilder({\n playlistUrlPattern:\n config.videoPlaylistUrlPattern ||\n `${config.publicUrl}/vid/%s/%s/playlist.m3u8`,\n thumbnailUrlPattern:\n config.videoThumbnailUrlPattern ||\n `${config.publicUrl}/vid/%s/%s/thumbnail.jpg`,\n })\n\n const searchClient = config.searchUrl\n ? new Client(\n {\n service: config.searchUrl,\n },\n {\n // Trust internal services to send us well-formed responses\n strictResponseProcessing: false,\n validateResponse: config.debugMode,\n },\n )\n : undefined\n\n const suggestionsClient = config.suggestionsUrl\n ? new Client(\n {\n service: config.suggestionsUrl,\n headers: config.suggestionsApiKey\n ? { authorization: `Bearer ${config.suggestionsApiKey}` }\n : undefined,\n },\n {\n // Trust internal services to send us well-formed responses\n strictResponseProcessing: false,\n validateResponse: config.debugMode,\n },\n )\n : undefined\n\n const topicsClient = config.topicsUrl\n ? new Client(\n {\n service: config.topicsUrl,\n headers: config.topicsApiKey\n ? { authorization: `Bearer ${config.topicsApiKey}` }\n : undefined,\n },\n {\n // Trust internal services to send us well-formed responses\n strictResponseProcessing: false,\n validateResponse: config.debugMode,\n },\n )\n : undefined\n\n const etcd = config.etcdHosts.length\n ? new Etcd3({ hosts: config.etcdHosts })\n : undefined\n\n const dataplaneHostList =\n etcd && config.dataplaneUrlsEtcdKeyPrefix\n ? new EtcdHostList(\n etcd,\n config.dataplaneUrlsEtcdKeyPrefix,\n config.dataplaneUrls,\n )\n : new BasicHostList(config.dataplaneUrls)\n\n const featureGatesClient = new FeatureGatesClient({\n growthBookApiHost: config.growthBookApiHost,\n growthBookClientKey: config.growthBookClientKey,\n eventProxyTrackingEndpoint: config.eventProxyTrackingEndpoint,\n })\n\n const dataplane = createDataPlaneClient(dataplaneHostList, {\n httpVersion: config.dataplaneHttpVersion,\n rejectUnauthorized: !config.dataplaneIgnoreBadTls,\n })\n const hydrator = new Hydrator(dataplane, config.labelsFromIssuerDids, {\n debugFieldAllowedDids: config.debugFieldAllowedDids,\n featureGatesClient,\n })\n const views = new Views({\n imgUriBuilder: imgUriBuilder,\n videoUriBuilder: videoUriBuilder,\n indexedAtEpoch: config.indexedAtEpoch,\n threadTagsBumpDown: [...config.threadTagsBumpDown],\n threadTagsHide: [...config.threadTagsHide],\n visibilityTagHide: config.visibilityTagHide,\n visibilityTagRankPrefix: config.visibilityTagRankPrefix,\n })\n\n const bsyncClient = createBsyncClient({\n baseUrl: config.bsyncUrl,\n httpVersion: config.bsyncHttpVersion ?? '2',\n nodeOptions: { rejectUnauthorized: !config.bsyncIgnoreBadTls },\n interceptors: config.bsyncApiKey ? [bsyncAuth(config.bsyncApiKey)] : [],\n })\n\n const stashClient = createStashClient(bsyncClient)\n\n const courierClient = config.courierUrl\n ? createCourierClient({\n baseUrl: config.courierUrl,\n httpVersion: config.courierHttpVersion ?? '2',\n nodeOptions: { rejectUnauthorized: !config.courierIgnoreBadTls },\n interceptors: config.courierApiKey\n ? [courierAuth(config.courierApiKey)]\n : [],\n })\n : undefined\n\n const rolodexClient = config.rolodexUrl\n ? createRolodexClient({\n baseUrl: config.rolodexUrl,\n httpVersion: config.rolodexHttpVersion ?? '2',\n nodeOptions: { rejectUnauthorized: !config.rolodexIgnoreBadTls },\n interceptors: config.rolodexApiKey\n ? [rolodexAuth(config.rolodexApiKey)]\n : [],\n })\n : undefined\n\n const kwsClient = config.kws ? createKwsClient(config.kws) : undefined\n\n const entrywayJwtPublicKey = config.entrywayJwtPublicKeyHex\n ? createPublicKeyObject(config.entrywayJwtPublicKeyHex)\n : undefined\n const authVerifier = new AuthVerifier(dataplane, {\n ownDid: config.serverDid,\n alternateAudienceDids: config.alternateAudienceDids,\n modServiceDid: config.modServiceDid,\n adminPasses: config.adminPasswords,\n entrywayJwtPublicKey,\n })\n\n const blobDispatcher = createBlobDispatcher(config)\n\n const ctx = new AppContext({\n cfg: config,\n etcd,\n dataplane,\n dataplaneHostList,\n searchClient,\n suggestionsClient,\n topicsClient,\n hydrator,\n views,\n signingKey,\n idResolver,\n bsyncClient,\n stashClient,\n courierClient,\n rolodexClient,\n authVerifier,\n featureGatesClient,\n blobDispatcher,\n kwsClient,\n })\n\n const server = createServer([], {\n validateResponse: config.debugMode,\n payload: {\n jsonLimit: 100 * 1024, // 100kb\n textLimit: 100 * 1024, // 100kb\n blobLimit: 5 * 1024 * 1024, // 5mb\n },\n })\n\n API(server, ctx)\n\n app.use(health.createRouter(ctx))\n app.use(wellKnown.createRouter(ctx))\n app.use(blobResolver.createMiddleware(ctx))\n app.use(imageServer.createMiddleware(ctx, { prefix: '/img/' }))\n\n if (config.dataplaneUrls.length > 0 || config.dataplaneUrlsEtcdKeyPrefix) {\n app.use(sitemap.createRouter(ctx))\n }\n\n app.use(server.router)\n app.use(error.handler)\n app.use('/external', external.createRouter(ctx))\n\n return new BskyAppView({ ctx, app })\n }\n\n async start(): Promise<http.Server> {\n if (this.ctx.dataplaneHostList instanceof EtcdHostList) {\n await this.ctx.dataplaneHostList.connect()\n }\n this.ctx.featureGatesClient.start() // lazy, no await\n const server = this.app.listen(this.ctx.cfg.port)\n this.server = server\n server.keepAliveTimeout = 90000\n this.terminator = httpTerminator.createHttpTerminator({ server })\n await events.once(server, 'listening')\n const { port } = server.address() as AddressInfo\n this.ctx.cfg.assignPort(port)\n return server\n }\n\n async destroy(): Promise<void> {\n try {\n await this.ctx.featureGatesClient.destroy()\n } finally {\n try {\n await this.terminator?.terminate()\n } finally {\n await this.ctx.etcd?.close()\n }\n }\n }\n\n async [Symbol.asyncDispose]() {\n await this.destroy()\n }\n}\n\nexport default BskyAppView\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"authFullApp.defs.d.ts","sourceRoot":"","sources":["../../../../src/lexicons/app/bsky/authFullApp.defs.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,CAAC,EAAE,MAAM,cAAc,CAAA;AAEhC,QAAA,MAAM,KAAK,yBAAyB,CAAA;AAEpC,OAAO,EAAE,KAAK,EAAE,CAAA;AAEhB,QAAA,MAAM,IAAI,iRAgIT,CAAA;AAED,OAAO,EAAE,IAAI,EAAE,CAAA"}
1
+ {"version":3,"file":"authFullApp.defs.d.ts","sourceRoot":"","sources":["../../../../src/lexicons/app/bsky/authFullApp.defs.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,CAAC,EAAE,MAAM,cAAc,CAAA;AAEhC,QAAA,MAAM,KAAK,yBAAyB,CAAA;AAEpC,OAAO,EAAE,KAAK,EAAE,CAAA;AAEhB,QAAA,MAAM,IAAI,iRAiIT,CAAA;AAED,OAAO,EAAE,IAAI,EAAE,CAAA"}
@@ -42,6 +42,7 @@ const main = /*#__PURE__*/ l.permissionSet($nsid, [
42
42
  'app.bsky.feed.getSuggestedFeeds',
43
43
  'app.bsky.feed.getTimeline',
44
44
  'app.bsky.feed.searchPosts',
45
+ 'app.bsky.feed.searchPostsV2',
45
46
  'app.bsky.feed.sendInteractions',
46
47
  'app.bsky.graph.getActorStarterPacks',
47
48
  'app.bsky.graph.getBlocks',
@@ -1 +1 @@
1
- {"version":3,"file":"authFullApp.defs.js","sourceRoot":"","sources":["../../../../src/lexicons/app/bsky/authFullApp.defs.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,cAAc,CAAA;AAEhC,MAAM,KAAK,GAAG,sBAAsB,CAAA;AAEpC,OAAO,EAAE,KAAK,EAAE,CAAA;AAEhB,MAAM,IAAI,GAAG,aAAa,CAAC,CAAC,CAAC,aAAa,CACxC,KAAK,EACL;IACE,aAAa,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,EAAE;QAChC,UAAU,EAAE,IAAI;QAChB,GAAG,EAAE;YACH,+BAA+B;YAC/B,2BAA2B;YAC3B,4BAA4B;YAC5B,+BAA+B;YAC/B,+BAA+B;YAC/B,6BAA6B;YAC7B,sCAAsC;YACtC,kCAAkC;YAClC,kCAAkC;YAClC,gCAAgC;YAChC,+BAA+B;YAC/B,6BAA6B;YAC7B,gCAAgC;YAChC,iCAAiC;YACjC,6BAA6B;YAC7B,yCAAyC;YACzC,8BAA8B;YAC9B,qCAAqC;YACrC,6BAA6B;YAC7B,6BAA6B;YAC7B,6BAA6B;YAC7B,uBAAuB;YACvB,gCAAgC;YAChC,iCAAiC;YACjC,+BAA+B;YAC/B,wBAAwB;YACxB,2BAA2B;YAC3B,6BAA6B;YAC7B,wBAAwB;YACxB,yBAAyB;YACzB,6BAA6B;YAC7B,iCAAiC;YACjC,2BAA2B;YAC3B,2BAA2B;YAC3B,gCAAgC;YAChC,qCAAqC;YACrC,0BAA0B;YAC1B,6BAA6B;YAC7B,2BAA2B;YAC3B,kCAAkC;YAClC,wBAAwB;YACxB,8BAA8B;YAC9B,6BAA6B;YAC7B,yBAAyB;YACzB,uCAAuC;YACvC,yBAAyB;YACzB,iCAAiC;YACjC,+BAA+B;YAC/B,gCAAgC;YAChC,8CAA8C;YAC9C,2CAA2C;YAC3C,0BAA0B;YAC1B,8BAA8B;YAC9B,2BAA2B;YAC3B,mCAAmC;YACnC,4BAA4B;YAC5B,gCAAgC;YAChC,6BAA6B;YAC7B,8BAA8B;YAC9B,sCAAsC;YACtC,sCAAsC;YACtC,iDAAiD;YACjD,yCAAyC;YACzC,+CAA+C;YAC/C,sCAAsC;YACtC,wCAAwC;YACxC,oCAAoC;YACpC,sCAAsC;YACtC,kCAAkC;YAClC,yCAAyC;YACzC,8BAA8B;YAC9B,uDAAuD;YACvD,6CAA6C;YAC7C,yCAAyC;YACzC,oCAAoC;YACpC,sCAAsC;YACtC,8CAA8C;YAC9C,6CAA6C;YAC7C,qDAAqD;YACrD,sCAAsC;YACtC,8CAA8C;YAC9C,2CAA2C;YAC3C,yCAAyC;YACzC,sCAAsC;YACtC,8BAA8B;YAC9B,sCAAsC;YACtC,qCAAqC;YACrC,yCAAyC;YACzC,wCAAwC;YACxC,+CAA+C;YAC/C,6BAA6B;YAC7B,gCAAgC;YAChC,4BAA4B;SAC7B;KACF,CAAC;IACF,aAAa,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,EAAE;QACjC,MAAM,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC;QACtC,UAAU,EAAE;YACV,wBAAwB;YACxB,uBAAuB;YACvB,oBAAoB;YACpB,oBAAoB;YACpB,wBAAwB;YACxB,sBAAsB;YACtB,0BAA0B;YAC1B,sBAAsB;YACtB,uBAAuB;YACvB,qBAAqB;YACrB,0BAA0B;YAC1B,yBAAyB;YACzB,4BAA4B;YAC5B,mCAAmC;SACpC;KACF,CAAC;CACH,EACD;IACE,KAAK,EAAE,qCAAqC;IAC5C,YAAY,EAAE,EAAE;IAChB,MAAM,EACJ,sIAAsI;IACxI,aAAa,EAAE,EAAE;CAClB,CACF,CAAA;AAED,OAAO,EAAE,IAAI,EAAE,CAAA","sourcesContent":["/*\n * THIS FILE WAS GENERATED BY \"@atproto/lex\". DO NOT EDIT.\n */\n\nimport { l } from '@atproto/lex'\n\nconst $nsid = 'app.bsky.authFullApp'\n\nexport { $nsid }\n\nconst main = /*#__PURE__*/ l.permissionSet(\n $nsid,\n [\n /*#__PURE__*/ l.permission('rpc', {\n inheritAud: true,\n lxm: [\n 'app.bsky.actor.getPreferences',\n 'app.bsky.actor.getProfile',\n 'app.bsky.actor.getProfiles',\n 'app.bsky.actor.getSuggestions',\n 'app.bsky.actor.putPreferences',\n 'app.bsky.actor.searchActors',\n 'app.bsky.actor.searchActorsTypeahead',\n 'app.bsky.bookmark.createBookmark',\n 'app.bsky.bookmark.deleteBookmark',\n 'app.bsky.bookmark.getBookmarks',\n 'app.bsky.contact.dismissMatch',\n 'app.bsky.contact.getMatches',\n 'app.bsky.contact.getSyncStatus',\n 'app.bsky.contact.importContacts',\n 'app.bsky.contact.removeData',\n 'app.bsky.contact.startPhoneVerification',\n 'app.bsky.contact.verifyPhone',\n 'app.bsky.feed.describeFeedGenerator',\n 'app.bsky.feed.getActorFeeds',\n 'app.bsky.feed.getActorLikes',\n 'app.bsky.feed.getAuthorFeed',\n 'app.bsky.feed.getFeed',\n 'app.bsky.feed.getFeedGenerator',\n 'app.bsky.feed.getFeedGenerators',\n 'app.bsky.feed.getFeedSkeleton',\n 'app.bsky.feed.getLikes',\n 'app.bsky.feed.getListFeed',\n 'app.bsky.feed.getPostThread',\n 'app.bsky.feed.getPosts',\n 'app.bsky.feed.getQuotes',\n 'app.bsky.feed.getRepostedBy',\n 'app.bsky.feed.getSuggestedFeeds',\n 'app.bsky.feed.getTimeline',\n 'app.bsky.feed.searchPosts',\n 'app.bsky.feed.sendInteractions',\n 'app.bsky.graph.getActorStarterPacks',\n 'app.bsky.graph.getBlocks',\n 'app.bsky.graph.getFollowers',\n 'app.bsky.graph.getFollows',\n 'app.bsky.graph.getKnownFollowers',\n 'app.bsky.graph.getList',\n 'app.bsky.graph.getListBlocks',\n 'app.bsky.graph.getListMutes',\n 'app.bsky.graph.getLists',\n 'app.bsky.graph.getListsWithMembership',\n 'app.bsky.graph.getMutes',\n 'app.bsky.graph.getRelationships',\n 'app.bsky.graph.getStarterPack',\n 'app.bsky.graph.getStarterPacks',\n 'app.bsky.graph.getStarterPacksWithMembership',\n 'app.bsky.graph.getSuggestedFollowsByActor',\n 'app.bsky.graph.muteActor',\n 'app.bsky.graph.muteActorList',\n 'app.bsky.graph.muteThread',\n 'app.bsky.graph.searchStarterPacks',\n 'app.bsky.graph.unmuteActor',\n 'app.bsky.graph.unmuteActorList',\n 'app.bsky.graph.unmuteThread',\n 'app.bsky.labeler.getServices',\n 'app.bsky.notification.getPreferences',\n 'app.bsky.notification.getUnreadCount',\n 'app.bsky.notification.listActivitySubscriptions',\n 'app.bsky.notification.listNotifications',\n 'app.bsky.notification.putActivitySubscription',\n 'app.bsky.notification.putPreferences',\n 'app.bsky.notification.putPreferencesV2',\n 'app.bsky.notification.registerPush',\n 'app.bsky.notification.unregisterPush',\n 'app.bsky.notification.updateSeen',\n 'app.bsky.unspecced.getAgeAssuranceState',\n 'app.bsky.unspecced.getConfig',\n 'app.bsky.unspecced.getOnboardingSuggestedStarterPacks',\n 'app.bsky.unspecced.getPopularFeedGenerators',\n 'app.bsky.unspecced.getPostThreadOtherV2',\n 'app.bsky.unspecced.getPostThreadV2',\n 'app.bsky.unspecced.getSuggestedFeeds',\n 'app.bsky.unspecced.getSuggestedFeedsSkeleton',\n 'app.bsky.unspecced.getSuggestedStarterPacks',\n 'app.bsky.unspecced.getSuggestedStarterPacksSkeleton',\n 'app.bsky.unspecced.getSuggestedUsers',\n 'app.bsky.unspecced.getSuggestedUsersSkeleton',\n 'app.bsky.unspecced.getSuggestionsSkeleton',\n 'app.bsky.unspecced.getTaggedSuggestions',\n 'app.bsky.unspecced.getTrendingTopics',\n 'app.bsky.unspecced.getTrends',\n 'app.bsky.unspecced.getTrendsSkeleton',\n 'app.bsky.unspecced.initAgeAssurance',\n 'app.bsky.unspecced.searchActorsSkeleton',\n 'app.bsky.unspecced.searchPostsSkeleton',\n 'app.bsky.unspecced.searchStarterPacksSkeleton',\n 'app.bsky.video.getJobStatus',\n 'app.bsky.video.getUploadLimits',\n 'app.bsky.video.uploadVideo',\n ],\n }),\n /*#__PURE__*/ l.permission('repo', {\n action: ['create', 'update', 'delete'],\n collection: [\n 'app.bsky.actor.profile',\n 'app.bsky.actor.status',\n 'app.bsky.feed.like',\n 'app.bsky.feed.post',\n 'app.bsky.feed.postgate',\n 'app.bsky.feed.repost',\n 'app.bsky.feed.threadgate',\n 'app.bsky.graph.block',\n 'app.bsky.graph.follow',\n 'app.bsky.graph.list',\n 'app.bsky.graph.listblock',\n 'app.bsky.graph.listitem',\n 'app.bsky.graph.starterpack',\n 'app.bsky.notification.declaration',\n ],\n }),\n ],\n {\n title: 'Full Bluesky Social App Permissions',\n 'title:lang': {},\n detail:\n 'Manage all public content and interactions, private preferences and subscriptions, and other Bluesky-specific app features and data.',\n 'detail:lang': {},\n },\n)\n\nexport { main }\n"]}
1
+ {"version":3,"file":"authFullApp.defs.js","sourceRoot":"","sources":["../../../../src/lexicons/app/bsky/authFullApp.defs.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,cAAc,CAAA;AAEhC,MAAM,KAAK,GAAG,sBAAsB,CAAA;AAEpC,OAAO,EAAE,KAAK,EAAE,CAAA;AAEhB,MAAM,IAAI,GAAG,aAAa,CAAC,CAAC,CAAC,aAAa,CACxC,KAAK,EACL;IACE,aAAa,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,EAAE;QAChC,UAAU,EAAE,IAAI;QAChB,GAAG,EAAE;YACH,+BAA+B;YAC/B,2BAA2B;YAC3B,4BAA4B;YAC5B,+BAA+B;YAC/B,+BAA+B;YAC/B,6BAA6B;YAC7B,sCAAsC;YACtC,kCAAkC;YAClC,kCAAkC;YAClC,gCAAgC;YAChC,+BAA+B;YAC/B,6BAA6B;YAC7B,gCAAgC;YAChC,iCAAiC;YACjC,6BAA6B;YAC7B,yCAAyC;YACzC,8BAA8B;YAC9B,qCAAqC;YACrC,6BAA6B;YAC7B,6BAA6B;YAC7B,6BAA6B;YAC7B,uBAAuB;YACvB,gCAAgC;YAChC,iCAAiC;YACjC,+BAA+B;YAC/B,wBAAwB;YACxB,2BAA2B;YAC3B,6BAA6B;YAC7B,wBAAwB;YACxB,yBAAyB;YACzB,6BAA6B;YAC7B,iCAAiC;YACjC,2BAA2B;YAC3B,2BAA2B;YAC3B,6BAA6B;YAC7B,gCAAgC;YAChC,qCAAqC;YACrC,0BAA0B;YAC1B,6BAA6B;YAC7B,2BAA2B;YAC3B,kCAAkC;YAClC,wBAAwB;YACxB,8BAA8B;YAC9B,6BAA6B;YAC7B,yBAAyB;YACzB,uCAAuC;YACvC,yBAAyB;YACzB,iCAAiC;YACjC,+BAA+B;YAC/B,gCAAgC;YAChC,8CAA8C;YAC9C,2CAA2C;YAC3C,0BAA0B;YAC1B,8BAA8B;YAC9B,2BAA2B;YAC3B,mCAAmC;YACnC,4BAA4B;YAC5B,gCAAgC;YAChC,6BAA6B;YAC7B,8BAA8B;YAC9B,sCAAsC;YACtC,sCAAsC;YACtC,iDAAiD;YACjD,yCAAyC;YACzC,+CAA+C;YAC/C,sCAAsC;YACtC,wCAAwC;YACxC,oCAAoC;YACpC,sCAAsC;YACtC,kCAAkC;YAClC,yCAAyC;YACzC,8BAA8B;YAC9B,uDAAuD;YACvD,6CAA6C;YAC7C,yCAAyC;YACzC,oCAAoC;YACpC,sCAAsC;YACtC,8CAA8C;YAC9C,6CAA6C;YAC7C,qDAAqD;YACrD,sCAAsC;YACtC,8CAA8C;YAC9C,2CAA2C;YAC3C,yCAAyC;YACzC,sCAAsC;YACtC,8BAA8B;YAC9B,sCAAsC;YACtC,qCAAqC;YACrC,yCAAyC;YACzC,wCAAwC;YACxC,+CAA+C;YAC/C,6BAA6B;YAC7B,gCAAgC;YAChC,4BAA4B;SAC7B;KACF,CAAC;IACF,aAAa,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,EAAE;QACjC,MAAM,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC;QACtC,UAAU,EAAE;YACV,wBAAwB;YACxB,uBAAuB;YACvB,oBAAoB;YACpB,oBAAoB;YACpB,wBAAwB;YACxB,sBAAsB;YACtB,0BAA0B;YAC1B,sBAAsB;YACtB,uBAAuB;YACvB,qBAAqB;YACrB,0BAA0B;YAC1B,yBAAyB;YACzB,4BAA4B;YAC5B,mCAAmC;SACpC;KACF,CAAC;CACH,EACD;IACE,KAAK,EAAE,qCAAqC;IAC5C,YAAY,EAAE,EAAE;IAChB,MAAM,EACJ,sIAAsI;IACxI,aAAa,EAAE,EAAE;CAClB,CACF,CAAA;AAED,OAAO,EAAE,IAAI,EAAE,CAAA","sourcesContent":["/*\n * THIS FILE WAS GENERATED BY \"@atproto/lex\". DO NOT EDIT.\n */\n\nimport { l } from '@atproto/lex'\n\nconst $nsid = 'app.bsky.authFullApp'\n\nexport { $nsid }\n\nconst main = /*#__PURE__*/ l.permissionSet(\n $nsid,\n [\n /*#__PURE__*/ l.permission('rpc', {\n inheritAud: true,\n lxm: [\n 'app.bsky.actor.getPreferences',\n 'app.bsky.actor.getProfile',\n 'app.bsky.actor.getProfiles',\n 'app.bsky.actor.getSuggestions',\n 'app.bsky.actor.putPreferences',\n 'app.bsky.actor.searchActors',\n 'app.bsky.actor.searchActorsTypeahead',\n 'app.bsky.bookmark.createBookmark',\n 'app.bsky.bookmark.deleteBookmark',\n 'app.bsky.bookmark.getBookmarks',\n 'app.bsky.contact.dismissMatch',\n 'app.bsky.contact.getMatches',\n 'app.bsky.contact.getSyncStatus',\n 'app.bsky.contact.importContacts',\n 'app.bsky.contact.removeData',\n 'app.bsky.contact.startPhoneVerification',\n 'app.bsky.contact.verifyPhone',\n 'app.bsky.feed.describeFeedGenerator',\n 'app.bsky.feed.getActorFeeds',\n 'app.bsky.feed.getActorLikes',\n 'app.bsky.feed.getAuthorFeed',\n 'app.bsky.feed.getFeed',\n 'app.bsky.feed.getFeedGenerator',\n 'app.bsky.feed.getFeedGenerators',\n 'app.bsky.feed.getFeedSkeleton',\n 'app.bsky.feed.getLikes',\n 'app.bsky.feed.getListFeed',\n 'app.bsky.feed.getPostThread',\n 'app.bsky.feed.getPosts',\n 'app.bsky.feed.getQuotes',\n 'app.bsky.feed.getRepostedBy',\n 'app.bsky.feed.getSuggestedFeeds',\n 'app.bsky.feed.getTimeline',\n 'app.bsky.feed.searchPosts',\n 'app.bsky.feed.searchPostsV2',\n 'app.bsky.feed.sendInteractions',\n 'app.bsky.graph.getActorStarterPacks',\n 'app.bsky.graph.getBlocks',\n 'app.bsky.graph.getFollowers',\n 'app.bsky.graph.getFollows',\n 'app.bsky.graph.getKnownFollowers',\n 'app.bsky.graph.getList',\n 'app.bsky.graph.getListBlocks',\n 'app.bsky.graph.getListMutes',\n 'app.bsky.graph.getLists',\n 'app.bsky.graph.getListsWithMembership',\n 'app.bsky.graph.getMutes',\n 'app.bsky.graph.getRelationships',\n 'app.bsky.graph.getStarterPack',\n 'app.bsky.graph.getStarterPacks',\n 'app.bsky.graph.getStarterPacksWithMembership',\n 'app.bsky.graph.getSuggestedFollowsByActor',\n 'app.bsky.graph.muteActor',\n 'app.bsky.graph.muteActorList',\n 'app.bsky.graph.muteThread',\n 'app.bsky.graph.searchStarterPacks',\n 'app.bsky.graph.unmuteActor',\n 'app.bsky.graph.unmuteActorList',\n 'app.bsky.graph.unmuteThread',\n 'app.bsky.labeler.getServices',\n 'app.bsky.notification.getPreferences',\n 'app.bsky.notification.getUnreadCount',\n 'app.bsky.notification.listActivitySubscriptions',\n 'app.bsky.notification.listNotifications',\n 'app.bsky.notification.putActivitySubscription',\n 'app.bsky.notification.putPreferences',\n 'app.bsky.notification.putPreferencesV2',\n 'app.bsky.notification.registerPush',\n 'app.bsky.notification.unregisterPush',\n 'app.bsky.notification.updateSeen',\n 'app.bsky.unspecced.getAgeAssuranceState',\n 'app.bsky.unspecced.getConfig',\n 'app.bsky.unspecced.getOnboardingSuggestedStarterPacks',\n 'app.bsky.unspecced.getPopularFeedGenerators',\n 'app.bsky.unspecced.getPostThreadOtherV2',\n 'app.bsky.unspecced.getPostThreadV2',\n 'app.bsky.unspecced.getSuggestedFeeds',\n 'app.bsky.unspecced.getSuggestedFeedsSkeleton',\n 'app.bsky.unspecced.getSuggestedStarterPacks',\n 'app.bsky.unspecced.getSuggestedStarterPacksSkeleton',\n 'app.bsky.unspecced.getSuggestedUsers',\n 'app.bsky.unspecced.getSuggestedUsersSkeleton',\n 'app.bsky.unspecced.getSuggestionsSkeleton',\n 'app.bsky.unspecced.getTaggedSuggestions',\n 'app.bsky.unspecced.getTrendingTopics',\n 'app.bsky.unspecced.getTrends',\n 'app.bsky.unspecced.getTrendsSkeleton',\n 'app.bsky.unspecced.initAgeAssurance',\n 'app.bsky.unspecced.searchActorsSkeleton',\n 'app.bsky.unspecced.searchPostsSkeleton',\n 'app.bsky.unspecced.searchStarterPacksSkeleton',\n 'app.bsky.video.getJobStatus',\n 'app.bsky.video.getUploadLimits',\n 'app.bsky.video.uploadVideo',\n ],\n }),\n /*#__PURE__*/ l.permission('repo', {\n action: ['create', 'update', 'delete'],\n collection: [\n 'app.bsky.actor.profile',\n 'app.bsky.actor.status',\n 'app.bsky.feed.like',\n 'app.bsky.feed.post',\n 'app.bsky.feed.postgate',\n 'app.bsky.feed.repost',\n 'app.bsky.feed.threadgate',\n 'app.bsky.graph.block',\n 'app.bsky.graph.follow',\n 'app.bsky.graph.list',\n 'app.bsky.graph.listblock',\n 'app.bsky.graph.listitem',\n 'app.bsky.graph.starterpack',\n 'app.bsky.notification.declaration',\n ],\n }),\n ],\n {\n title: 'Full Bluesky Social App Permissions',\n 'title:lang': {},\n detail:\n 'Manage all public content and interactions, private preferences and subscriptions, and other Bluesky-specific app features and data.',\n 'detail:lang': {},\n },\n)\n\nexport { main }\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"authViewAll.defs.d.ts","sourceRoot":"","sources":["../../../../src/lexicons/app/bsky/authViewAll.defs.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,CAAC,EAAE,MAAM,cAAc,CAAA;AAEhC,QAAA,MAAM,KAAK,yBAAyB,CAAA;AAEpC,OAAO,EAAE,KAAK,EAAE,CAAA;AAEhB,QAAA,MAAM,IAAI,kKAmFT,CAAA;AAED,OAAO,EAAE,IAAI,EAAE,CAAA"}
1
+ {"version":3,"file":"authViewAll.defs.d.ts","sourceRoot":"","sources":["../../../../src/lexicons/app/bsky/authViewAll.defs.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,CAAC,EAAE,MAAM,cAAc,CAAA;AAEhC,QAAA,MAAM,KAAK,yBAAyB,CAAA;AAEpC,OAAO,EAAE,KAAK,EAAE,CAAA;AAEhB,QAAA,MAAM,IAAI,kKAoFT,CAAA;AAED,OAAO,EAAE,IAAI,EAAE,CAAA"}
@@ -32,6 +32,7 @@ const main = /*#__PURE__*/ l.permissionSet($nsid, [
32
32
  'app.bsky.feed.getSuggestedFeeds',
33
33
  'app.bsky.feed.getTimeline',
34
34
  'app.bsky.feed.searchPosts',
35
+ 'app.bsky.feed.searchPostsV2',
35
36
  'app.bsky.graph.getActorStarterPacks',
36
37
  'app.bsky.graph.getBlocks',
37
38
  'app.bsky.graph.getFollowers',
@@ -1 +1 @@
1
- {"version":3,"file":"authViewAll.defs.js","sourceRoot":"","sources":["../../../../src/lexicons/app/bsky/authViewAll.defs.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,cAAc,CAAA;AAEhC,MAAM,KAAK,GAAG,sBAAsB,CAAA;AAEpC,OAAO,EAAE,KAAK,EAAE,CAAA;AAEhB,MAAM,IAAI,GAAG,aAAa,CAAC,CAAC,CAAC,aAAa,CACxC,KAAK,EACL;IACE,aAAa,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,EAAE;QAChC,UAAU,EAAE,IAAI;QAChB,GAAG,EAAE;YACH,+BAA+B;YAC/B,2BAA2B;YAC3B,4BAA4B;YAC5B,+BAA+B;YAC/B,6BAA6B;YAC7B,sCAAsC;YACtC,gCAAgC;YAChC,qCAAqC;YACrC,6BAA6B;YAC7B,6BAA6B;YAC7B,6BAA6B;YAC7B,uBAAuB;YACvB,gCAAgC;YAChC,iCAAiC;YACjC,+BAA+B;YAC/B,wBAAwB;YACxB,2BAA2B;YAC3B,6BAA6B;YAC7B,wBAAwB;YACxB,yBAAyB;YACzB,6BAA6B;YAC7B,iCAAiC;YACjC,2BAA2B;YAC3B,2BAA2B;YAC3B,qCAAqC;YACrC,0BAA0B;YAC1B,6BAA6B;YAC7B,2BAA2B;YAC3B,kCAAkC;YAClC,8BAA8B;YAC9B,6BAA6B;YAC7B,yBAAyB;YACzB,uCAAuC;YACvC,yBAAyB;YACzB,iCAAiC;YACjC,+BAA+B;YAC/B,gCAAgC;YAChC,8CAA8C;YAC9C,2CAA2C;YAC3C,mCAAmC;YACnC,8BAA8B;YAC9B,sCAAsC;YACtC,sCAAsC;YACtC,iDAAiD;YACjD,yCAAyC;YACzC,kCAAkC;YAClC,yCAAyC;YACzC,8BAA8B;YAC9B,uDAAuD;YACvD,6CAA6C;YAC7C,yCAAyC;YACzC,oCAAoC;YACpC,sCAAsC;YACtC,8CAA8C;YAC9C,6CAA6C;YAC7C,qDAAqD;YACrD,sCAAsC;YACtC,8CAA8C;YAC9C,2CAA2C;YAC3C,yCAAyC;YACzC,sCAAsC;YACtC,8BAA8B;YAC9B,sCAAsC;YACtC,yCAAyC;YACzC,wCAAwC;YACxC,+CAA+C;YAC/C,gCAAgC;SACjC;KACF,CAAC;CACH,EACD;IACE,KAAK,EAAE,iCAAiC;IACxC,YAAY,EAAE,EAAE;IAChB,MAAM,EACJ,oGAAoG;IACtG,aAAa,EAAE,EAAE;CAClB,CACF,CAAA;AAED,OAAO,EAAE,IAAI,EAAE,CAAA","sourcesContent":["/*\n * THIS FILE WAS GENERATED BY \"@atproto/lex\". DO NOT EDIT.\n */\n\nimport { l } from '@atproto/lex'\n\nconst $nsid = 'app.bsky.authViewAll'\n\nexport { $nsid }\n\nconst main = /*#__PURE__*/ l.permissionSet(\n $nsid,\n [\n /*#__PURE__*/ l.permission('rpc', {\n inheritAud: true,\n lxm: [\n 'app.bsky.actor.getPreferences',\n 'app.bsky.actor.getProfile',\n 'app.bsky.actor.getProfiles',\n 'app.bsky.actor.getSuggestions',\n 'app.bsky.actor.searchActors',\n 'app.bsky.actor.searchActorsTypeahead',\n 'app.bsky.bookmark.getBookmarks',\n 'app.bsky.feed.describeFeedGenerator',\n 'app.bsky.feed.getActorFeeds',\n 'app.bsky.feed.getActorLikes',\n 'app.bsky.feed.getAuthorFeed',\n 'app.bsky.feed.getFeed',\n 'app.bsky.feed.getFeedGenerator',\n 'app.bsky.feed.getFeedGenerators',\n 'app.bsky.feed.getFeedSkeleton',\n 'app.bsky.feed.getLikes',\n 'app.bsky.feed.getListFeed',\n 'app.bsky.feed.getPostThread',\n 'app.bsky.feed.getPosts',\n 'app.bsky.feed.getQuotes',\n 'app.bsky.feed.getRepostedBy',\n 'app.bsky.feed.getSuggestedFeeds',\n 'app.bsky.feed.getTimeline',\n 'app.bsky.feed.searchPosts',\n 'app.bsky.graph.getActorStarterPacks',\n 'app.bsky.graph.getBlocks',\n 'app.bsky.graph.getFollowers',\n 'app.bsky.graph.getFollows',\n 'app.bsky.graph.getKnownFollowers',\n 'app.bsky.graph.getListBlocks',\n 'app.bsky.graph.getListMutes',\n 'app.bsky.graph.getLists',\n 'app.bsky.graph.getListsWithMembership',\n 'app.bsky.graph.getMutes',\n 'app.bsky.graph.getRelationships',\n 'app.bsky.graph.getStarterPack',\n 'app.bsky.graph.getStarterPacks',\n 'app.bsky.graph.getStarterPacksWithMembership',\n 'app.bsky.graph.getSuggestedFollowsByActor',\n 'app.bsky.graph.searchStarterPacks',\n 'app.bsky.labeler.getServices',\n 'app.bsky.notification.getPreferences',\n 'app.bsky.notification.getUnreadCount',\n 'app.bsky.notification.listActivitySubscriptions',\n 'app.bsky.notification.listNotifications',\n 'app.bsky.notification.updateSeen',\n 'app.bsky.unspecced.getAgeAssuranceState',\n 'app.bsky.unspecced.getConfig',\n 'app.bsky.unspecced.getOnboardingSuggestedStarterPacks',\n 'app.bsky.unspecced.getPopularFeedGenerators',\n 'app.bsky.unspecced.getPostThreadOtherV2',\n 'app.bsky.unspecced.getPostThreadV2',\n 'app.bsky.unspecced.getSuggestedFeeds',\n 'app.bsky.unspecced.getSuggestedFeedsSkeleton',\n 'app.bsky.unspecced.getSuggestedStarterPacks',\n 'app.bsky.unspecced.getSuggestedStarterPacksSkeleton',\n 'app.bsky.unspecced.getSuggestedUsers',\n 'app.bsky.unspecced.getSuggestedUsersSkeleton',\n 'app.bsky.unspecced.getSuggestionsSkeleton',\n 'app.bsky.unspecced.getTaggedSuggestions',\n 'app.bsky.unspecced.getTrendingTopics',\n 'app.bsky.unspecced.getTrends',\n 'app.bsky.unspecced.getTrendsSkeleton',\n 'app.bsky.unspecced.searchActorsSkeleton',\n 'app.bsky.unspecced.searchPostsSkeleton',\n 'app.bsky.unspecced.searchStarterPacksSkeleton',\n 'app.bsky.video.getUploadLimits',\n ],\n }),\n ],\n {\n title: 'Read-only access to all content',\n 'title:lang': {},\n detail:\n 'View Bluesky network content from account perspective, and read all notifications and preferences.',\n 'detail:lang': {},\n },\n)\n\nexport { main }\n"]}
1
+ {"version":3,"file":"authViewAll.defs.js","sourceRoot":"","sources":["../../../../src/lexicons/app/bsky/authViewAll.defs.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,cAAc,CAAA;AAEhC,MAAM,KAAK,GAAG,sBAAsB,CAAA;AAEpC,OAAO,EAAE,KAAK,EAAE,CAAA;AAEhB,MAAM,IAAI,GAAG,aAAa,CAAC,CAAC,CAAC,aAAa,CACxC,KAAK,EACL;IACE,aAAa,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,EAAE;QAChC,UAAU,EAAE,IAAI;QAChB,GAAG,EAAE;YACH,+BAA+B;YAC/B,2BAA2B;YAC3B,4BAA4B;YAC5B,+BAA+B;YAC/B,6BAA6B;YAC7B,sCAAsC;YACtC,gCAAgC;YAChC,qCAAqC;YACrC,6BAA6B;YAC7B,6BAA6B;YAC7B,6BAA6B;YAC7B,uBAAuB;YACvB,gCAAgC;YAChC,iCAAiC;YACjC,+BAA+B;YAC/B,wBAAwB;YACxB,2BAA2B;YAC3B,6BAA6B;YAC7B,wBAAwB;YACxB,yBAAyB;YACzB,6BAA6B;YAC7B,iCAAiC;YACjC,2BAA2B;YAC3B,2BAA2B;YAC3B,6BAA6B;YAC7B,qCAAqC;YACrC,0BAA0B;YAC1B,6BAA6B;YAC7B,2BAA2B;YAC3B,kCAAkC;YAClC,8BAA8B;YAC9B,6BAA6B;YAC7B,yBAAyB;YACzB,uCAAuC;YACvC,yBAAyB;YACzB,iCAAiC;YACjC,+BAA+B;YAC/B,gCAAgC;YAChC,8CAA8C;YAC9C,2CAA2C;YAC3C,mCAAmC;YACnC,8BAA8B;YAC9B,sCAAsC;YACtC,sCAAsC;YACtC,iDAAiD;YACjD,yCAAyC;YACzC,kCAAkC;YAClC,yCAAyC;YACzC,8BAA8B;YAC9B,uDAAuD;YACvD,6CAA6C;YAC7C,yCAAyC;YACzC,oCAAoC;YACpC,sCAAsC;YACtC,8CAA8C;YAC9C,6CAA6C;YAC7C,qDAAqD;YACrD,sCAAsC;YACtC,8CAA8C;YAC9C,2CAA2C;YAC3C,yCAAyC;YACzC,sCAAsC;YACtC,8BAA8B;YAC9B,sCAAsC;YACtC,yCAAyC;YACzC,wCAAwC;YACxC,+CAA+C;YAC/C,gCAAgC;SACjC;KACF,CAAC;CACH,EACD;IACE,KAAK,EAAE,iCAAiC;IACxC,YAAY,EAAE,EAAE;IAChB,MAAM,EACJ,oGAAoG;IACtG,aAAa,EAAE,EAAE;CAClB,CACF,CAAA;AAED,OAAO,EAAE,IAAI,EAAE,CAAA","sourcesContent":["/*\n * THIS FILE WAS GENERATED BY \"@atproto/lex\". DO NOT EDIT.\n */\n\nimport { l } from '@atproto/lex'\n\nconst $nsid = 'app.bsky.authViewAll'\n\nexport { $nsid }\n\nconst main = /*#__PURE__*/ l.permissionSet(\n $nsid,\n [\n /*#__PURE__*/ l.permission('rpc', {\n inheritAud: true,\n lxm: [\n 'app.bsky.actor.getPreferences',\n 'app.bsky.actor.getProfile',\n 'app.bsky.actor.getProfiles',\n 'app.bsky.actor.getSuggestions',\n 'app.bsky.actor.searchActors',\n 'app.bsky.actor.searchActorsTypeahead',\n 'app.bsky.bookmark.getBookmarks',\n 'app.bsky.feed.describeFeedGenerator',\n 'app.bsky.feed.getActorFeeds',\n 'app.bsky.feed.getActorLikes',\n 'app.bsky.feed.getAuthorFeed',\n 'app.bsky.feed.getFeed',\n 'app.bsky.feed.getFeedGenerator',\n 'app.bsky.feed.getFeedGenerators',\n 'app.bsky.feed.getFeedSkeleton',\n 'app.bsky.feed.getLikes',\n 'app.bsky.feed.getListFeed',\n 'app.bsky.feed.getPostThread',\n 'app.bsky.feed.getPosts',\n 'app.bsky.feed.getQuotes',\n 'app.bsky.feed.getRepostedBy',\n 'app.bsky.feed.getSuggestedFeeds',\n 'app.bsky.feed.getTimeline',\n 'app.bsky.feed.searchPosts',\n 'app.bsky.feed.searchPostsV2',\n 'app.bsky.graph.getActorStarterPacks',\n 'app.bsky.graph.getBlocks',\n 'app.bsky.graph.getFollowers',\n 'app.bsky.graph.getFollows',\n 'app.bsky.graph.getKnownFollowers',\n 'app.bsky.graph.getListBlocks',\n 'app.bsky.graph.getListMutes',\n 'app.bsky.graph.getLists',\n 'app.bsky.graph.getListsWithMembership',\n 'app.bsky.graph.getMutes',\n 'app.bsky.graph.getRelationships',\n 'app.bsky.graph.getStarterPack',\n 'app.bsky.graph.getStarterPacks',\n 'app.bsky.graph.getStarterPacksWithMembership',\n 'app.bsky.graph.getSuggestedFollowsByActor',\n 'app.bsky.graph.searchStarterPacks',\n 'app.bsky.labeler.getServices',\n 'app.bsky.notification.getPreferences',\n 'app.bsky.notification.getUnreadCount',\n 'app.bsky.notification.listActivitySubscriptions',\n 'app.bsky.notification.listNotifications',\n 'app.bsky.notification.updateSeen',\n 'app.bsky.unspecced.getAgeAssuranceState',\n 'app.bsky.unspecced.getConfig',\n 'app.bsky.unspecced.getOnboardingSuggestedStarterPacks',\n 'app.bsky.unspecced.getPopularFeedGenerators',\n 'app.bsky.unspecced.getPostThreadOtherV2',\n 'app.bsky.unspecced.getPostThreadV2',\n 'app.bsky.unspecced.getSuggestedFeeds',\n 'app.bsky.unspecced.getSuggestedFeedsSkeleton',\n 'app.bsky.unspecced.getSuggestedStarterPacks',\n 'app.bsky.unspecced.getSuggestedStarterPacksSkeleton',\n 'app.bsky.unspecced.getSuggestedUsers',\n 'app.bsky.unspecced.getSuggestedUsersSkeleton',\n 'app.bsky.unspecced.getSuggestionsSkeleton',\n 'app.bsky.unspecced.getTaggedSuggestions',\n 'app.bsky.unspecced.getTrendingTopics',\n 'app.bsky.unspecced.getTrends',\n 'app.bsky.unspecced.getTrendsSkeleton',\n 'app.bsky.unspecced.searchActorsSkeleton',\n 'app.bsky.unspecced.searchPostsSkeleton',\n 'app.bsky.unspecced.searchStarterPacksSkeleton',\n 'app.bsky.video.getUploadLimits',\n ],\n }),\n ],\n {\n title: 'Read-only access to all content',\n 'title:lang': {},\n detail:\n 'View Bluesky network content from account perspective, and read all notifications and preferences.',\n 'detail:lang': {},\n },\n)\n\nexport { main }\n"]}
@@ -0,0 +1,3 @@
1
+ export * from './searchPostsV2.defs.js';
2
+ export { main as default } from './searchPostsV2.defs.js';
3
+ //# sourceMappingURL=searchPostsV2.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"searchPostsV2.d.ts","sourceRoot":"","sources":["../../../../../src/lexicons/app/bsky/feed/searchPostsV2.ts"],"names":[],"mappings":"AAIA,cAAc,yBAAyB,CAAA;AACvC,OAAO,EAAE,IAAI,IAAI,OAAO,EAAE,MAAM,yBAAyB,CAAA"}