@atproto/bsky 0.0.244 → 0.0.246

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 (144) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/api/app/bsky/feed/searchPostsV2.d.ts +4 -0
  3. package/dist/api/app/bsky/feed/searchPostsV2.d.ts.map +1 -0
  4. package/dist/api/app/bsky/feed/searchPostsV2.js +172 -0
  5. package/dist/api/app/bsky/feed/searchPostsV2.js.map +1 -0
  6. package/dist/api/index.d.ts.map +1 -1
  7. package/dist/api/index.js +2 -0
  8. package/dist/api/index.js.map +1 -1
  9. package/dist/data-plane/server/routes/search.js +1 -0
  10. package/dist/data-plane/server/routes/search.js.map +1 -1
  11. package/dist/lexicons/app/bsky/authFullApp.defs.d.ts.map +1 -1
  12. package/dist/lexicons/app/bsky/authFullApp.defs.js +1 -0
  13. package/dist/lexicons/app/bsky/authFullApp.defs.js.map +1 -1
  14. package/dist/lexicons/app/bsky/authViewAll.defs.d.ts.map +1 -1
  15. package/dist/lexicons/app/bsky/authViewAll.defs.js +1 -0
  16. package/dist/lexicons/app/bsky/authViewAll.defs.js.map +1 -1
  17. package/dist/lexicons/app/bsky/feed/searchPostsV2.d.ts +3 -0
  18. package/dist/lexicons/app/bsky/feed/searchPostsV2.d.ts.map +1 -0
  19. package/dist/lexicons/app/bsky/feed/searchPostsV2.defs.d.ts +158 -0
  20. package/dist/lexicons/app/bsky/feed/searchPostsV2.defs.d.ts.map +1 -0
  21. package/dist/lexicons/app/bsky/feed/searchPostsV2.defs.js +74 -0
  22. package/dist/lexicons/app/bsky/feed/searchPostsV2.defs.js.map +1 -0
  23. package/dist/lexicons/app/bsky/feed/searchPostsV2.js +6 -0
  24. package/dist/lexicons/app/bsky/feed/searchPostsV2.js.map +1 -0
  25. package/dist/lexicons/app/bsky/feed.d.ts +1 -0
  26. package/dist/lexicons/app/bsky/feed.d.ts.map +1 -1
  27. package/dist/lexicons/app/bsky/feed.js +1 -0
  28. package/dist/lexicons/app/bsky/feed.js.map +1 -1
  29. package/dist/lexicons/chat/bsky/actor/declaration.defs.d.ts +1 -1
  30. package/dist/lexicons/chat/bsky/actor/declaration.defs.js.map +1 -1
  31. package/dist/lexicons/chat/bsky/actor/defs.defs.d.ts +4 -6
  32. package/dist/lexicons/chat/bsky/actor/defs.defs.d.ts.map +1 -1
  33. package/dist/lexicons/chat/bsky/actor/defs.defs.js +2 -3
  34. package/dist/lexicons/chat/bsky/actor/defs.defs.js.map +1 -1
  35. package/dist/lexicons/chat/bsky/convo/defs.defs.d.ts +64 -70
  36. package/dist/lexicons/chat/bsky/convo/defs.defs.d.ts.map +1 -1
  37. package/dist/lexicons/chat/bsky/convo/defs.defs.js +32 -35
  38. package/dist/lexicons/chat/bsky/convo/defs.defs.js.map +1 -1
  39. package/dist/lexicons/chat/bsky/convo/getUnreadCounts.defs.d.ts +1 -1
  40. package/dist/lexicons/chat/bsky/convo/getUnreadCounts.defs.d.ts.map +1 -1
  41. package/dist/lexicons/chat/bsky/convo/getUnreadCounts.defs.js +1 -1
  42. package/dist/lexicons/chat/bsky/convo/getUnreadCounts.defs.js.map +1 -1
  43. package/dist/lexicons/chat/bsky/convo/listConvoRequests.defs.d.ts +1 -1
  44. package/dist/lexicons/chat/bsky/convo/listConvoRequests.defs.d.ts.map +1 -1
  45. package/dist/lexicons/chat/bsky/convo/listConvoRequests.defs.js +1 -1
  46. package/dist/lexicons/chat/bsky/convo/listConvoRequests.defs.js.map +1 -1
  47. package/dist/lexicons/chat/bsky/convo/lockConvo.defs.d.ts +1 -1
  48. package/dist/lexicons/chat/bsky/convo/lockConvo.defs.d.ts.map +1 -1
  49. package/dist/lexicons/chat/bsky/convo/lockConvo.defs.js +1 -1
  50. package/dist/lexicons/chat/bsky/convo/lockConvo.defs.js.map +1 -1
  51. package/dist/lexicons/chat/bsky/convo/unlockConvo.defs.d.ts +1 -1
  52. package/dist/lexicons/chat/bsky/convo/unlockConvo.defs.d.ts.map +1 -1
  53. package/dist/lexicons/chat/bsky/convo/unlockConvo.defs.js +1 -1
  54. package/dist/lexicons/chat/bsky/convo/unlockConvo.defs.js.map +1 -1
  55. package/dist/lexicons/chat/bsky/group/addMembers.defs.d.ts +1 -1
  56. package/dist/lexicons/chat/bsky/group/addMembers.defs.d.ts.map +1 -1
  57. package/dist/lexicons/chat/bsky/group/addMembers.defs.js +1 -1
  58. package/dist/lexicons/chat/bsky/group/addMembers.defs.js.map +1 -1
  59. package/dist/lexicons/chat/bsky/group/approveJoinRequest.defs.d.ts +1 -1
  60. package/dist/lexicons/chat/bsky/group/approveJoinRequest.defs.d.ts.map +1 -1
  61. package/dist/lexicons/chat/bsky/group/approveJoinRequest.defs.js +1 -1
  62. package/dist/lexicons/chat/bsky/group/approveJoinRequest.defs.js.map +1 -1
  63. package/dist/lexicons/chat/bsky/group/createGroup.defs.d.ts +1 -1
  64. package/dist/lexicons/chat/bsky/group/createGroup.defs.d.ts.map +1 -1
  65. package/dist/lexicons/chat/bsky/group/createGroup.defs.js +1 -1
  66. package/dist/lexicons/chat/bsky/group/createGroup.defs.js.map +1 -1
  67. package/dist/lexicons/chat/bsky/group/createJoinLink.defs.d.ts +1 -1
  68. package/dist/lexicons/chat/bsky/group/createJoinLink.defs.d.ts.map +1 -1
  69. package/dist/lexicons/chat/bsky/group/createJoinLink.defs.js +1 -1
  70. package/dist/lexicons/chat/bsky/group/createJoinLink.defs.js.map +1 -1
  71. package/dist/lexicons/chat/bsky/group/disableJoinLink.defs.d.ts +1 -1
  72. package/dist/lexicons/chat/bsky/group/disableJoinLink.defs.d.ts.map +1 -1
  73. package/dist/lexicons/chat/bsky/group/disableJoinLink.defs.js +1 -1
  74. package/dist/lexicons/chat/bsky/group/disableJoinLink.defs.js.map +1 -1
  75. package/dist/lexicons/chat/bsky/group/editGroup.defs.d.ts +1 -1
  76. package/dist/lexicons/chat/bsky/group/editGroup.defs.d.ts.map +1 -1
  77. package/dist/lexicons/chat/bsky/group/editGroup.defs.js +1 -1
  78. package/dist/lexicons/chat/bsky/group/editGroup.defs.js.map +1 -1
  79. package/dist/lexicons/chat/bsky/group/editJoinLink.defs.d.ts +1 -1
  80. package/dist/lexicons/chat/bsky/group/editJoinLink.defs.d.ts.map +1 -1
  81. package/dist/lexicons/chat/bsky/group/editJoinLink.defs.js +1 -1
  82. package/dist/lexicons/chat/bsky/group/editJoinLink.defs.js.map +1 -1
  83. package/dist/lexicons/chat/bsky/group/enableJoinLink.defs.d.ts +1 -1
  84. package/dist/lexicons/chat/bsky/group/enableJoinLink.defs.d.ts.map +1 -1
  85. package/dist/lexicons/chat/bsky/group/enableJoinLink.defs.js +1 -1
  86. package/dist/lexicons/chat/bsky/group/enableJoinLink.defs.js.map +1 -1
  87. package/dist/lexicons/chat/bsky/group/getJoinLinkPreviews.defs.d.ts +1 -1
  88. package/dist/lexicons/chat/bsky/group/getJoinLinkPreviews.defs.d.ts.map +1 -1
  89. package/dist/lexicons/chat/bsky/group/getJoinLinkPreviews.defs.js +1 -1
  90. package/dist/lexicons/chat/bsky/group/getJoinLinkPreviews.defs.js.map +1 -1
  91. package/dist/lexicons/chat/bsky/group/listJoinRequests.defs.d.ts +1 -1
  92. package/dist/lexicons/chat/bsky/group/listJoinRequests.defs.d.ts.map +1 -1
  93. package/dist/lexicons/chat/bsky/group/listJoinRequests.defs.js +1 -1
  94. package/dist/lexicons/chat/bsky/group/listJoinRequests.defs.js.map +1 -1
  95. package/dist/lexicons/chat/bsky/group/listMutualGroups.defs.d.ts +1 -1
  96. package/dist/lexicons/chat/bsky/group/listMutualGroups.defs.d.ts.map +1 -1
  97. package/dist/lexicons/chat/bsky/group/listMutualGroups.defs.js +1 -1
  98. package/dist/lexicons/chat/bsky/group/listMutualGroups.defs.js.map +1 -1
  99. package/dist/lexicons/chat/bsky/group/rejectJoinRequest.defs.d.ts +1 -1
  100. package/dist/lexicons/chat/bsky/group/rejectJoinRequest.defs.d.ts.map +1 -1
  101. package/dist/lexicons/chat/bsky/group/rejectJoinRequest.defs.js +1 -1
  102. package/dist/lexicons/chat/bsky/group/rejectJoinRequest.defs.js.map +1 -1
  103. package/dist/lexicons/chat/bsky/group/removeMembers.defs.d.ts +1 -1
  104. package/dist/lexicons/chat/bsky/group/removeMembers.defs.d.ts.map +1 -1
  105. package/dist/lexicons/chat/bsky/group/removeMembers.defs.js +1 -1
  106. package/dist/lexicons/chat/bsky/group/removeMembers.defs.js.map +1 -1
  107. package/dist/lexicons/chat/bsky/group/requestJoin.defs.d.ts +1 -1
  108. package/dist/lexicons/chat/bsky/group/requestJoin.defs.d.ts.map +1 -1
  109. package/dist/lexicons/chat/bsky/group/requestJoin.defs.js +1 -1
  110. package/dist/lexicons/chat/bsky/group/requestJoin.defs.js.map +1 -1
  111. package/dist/lexicons/chat/bsky/group/updateJoinRequestsRead.defs.d.ts +1 -1
  112. package/dist/lexicons/chat/bsky/group/updateJoinRequestsRead.defs.d.ts.map +1 -1
  113. package/dist/lexicons/chat/bsky/group/updateJoinRequestsRead.defs.js +1 -1
  114. package/dist/lexicons/chat/bsky/group/updateJoinRequestsRead.defs.js.map +1 -1
  115. package/dist/lexicons/chat/bsky/group/withdrawJoinRequest.defs.d.ts +1 -1
  116. package/dist/lexicons/chat/bsky/group/withdrawJoinRequest.defs.d.ts.map +1 -1
  117. package/dist/lexicons/chat/bsky/group/withdrawJoinRequest.defs.js +1 -1
  118. package/dist/lexicons/chat/bsky/group/withdrawJoinRequest.defs.js.map +1 -1
  119. package/dist/lexicons/chat/bsky/moderation/defs.defs.d.ts +6 -6
  120. package/dist/lexicons/chat/bsky/moderation/defs.defs.d.ts.map +1 -1
  121. package/dist/lexicons/chat/bsky/moderation/defs.defs.js +3 -3
  122. package/dist/lexicons/chat/bsky/moderation/defs.defs.js.map +1 -1
  123. package/dist/lexicons/chat/bsky/moderation/getConvo.defs.d.ts +1 -1
  124. package/dist/lexicons/chat/bsky/moderation/getConvo.defs.d.ts.map +1 -1
  125. package/dist/lexicons/chat/bsky/moderation/getConvo.defs.js +1 -1
  126. package/dist/lexicons/chat/bsky/moderation/getConvo.defs.js.map +1 -1
  127. package/dist/lexicons/chat/bsky/moderation/getConvoMembers.defs.d.ts +1 -1
  128. package/dist/lexicons/chat/bsky/moderation/getConvoMembers.defs.d.ts.map +1 -1
  129. package/dist/lexicons/chat/bsky/moderation/getConvoMembers.defs.js +1 -1
  130. package/dist/lexicons/chat/bsky/moderation/getConvoMembers.defs.js.map +1 -1
  131. package/dist/lexicons/chat/bsky/moderation/getConvos.defs.d.ts +1 -1
  132. package/dist/lexicons/chat/bsky/moderation/getConvos.defs.d.ts.map +1 -1
  133. package/dist/lexicons/chat/bsky/moderation/getConvos.defs.js +1 -1
  134. package/dist/lexicons/chat/bsky/moderation/getConvos.defs.js.map +1 -1
  135. package/dist/proto/bsky_pb.d.ts +4 -2
  136. package/dist/proto/bsky_pb.d.ts.map +1 -1
  137. package/dist/proto/bsky_pb.js +5 -3
  138. package/dist/proto/bsky_pb.js.map +1 -1
  139. package/package.json +9 -9
  140. package/proto/bsky.proto +2 -1
  141. package/src/api/app/bsky/feed/searchPostsV2.ts +235 -0
  142. package/src/api/index.ts +2 -0
  143. package/src/data-plane/server/routes/search.ts +1 -0
  144. package/tsconfig.build.tsbuildinfo +1 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atproto/bsky",
3
- "version": "0.0.244",
3
+ "version": "0.0.246",
4
4
  "license": "MIT",
5
5
  "description": "Reference implementation of app.bsky App View (Bluesky API)",
6
6
  "keywords": [
@@ -49,17 +49,17 @@
49
49
  "undici": "^8.5.0",
50
50
  "zod": "3.23.8",
51
51
  "@atproto-labs/fetch-node": "^0.3.2",
52
- "@atproto/api": "^0.20.17",
53
- "@atproto/crypto": "^0.5.1",
54
- "@atproto/common": "^0.6.3",
55
- "@atproto/did": "^0.5.1",
56
52
  "@atproto-labs/xrpc-utils": "^0.1.1",
57
- "@atproto/lex": "^0.1.4",
58
- "@atproto/repo": "^0.10.1",
53
+ "@atproto/api": "^0.20.19",
54
+ "@atproto/crypto": "^0.5.1",
59
55
  "@atproto/identity": "^0.5.1",
56
+ "@atproto/repo": "^0.10.1",
60
57
  "@atproto/sync": "^0.3.3",
61
- "@atproto/syntax": "^0.6.2",
62
- "@atproto/xrpc-server": "^0.11.2"
58
+ "@atproto/lex": "^0.1.4",
59
+ "@atproto/common": "^0.6.3",
60
+ "@atproto/did": "^0.5.1",
61
+ "@atproto/xrpc-server": "^0.11.2",
62
+ "@atproto/syntax": "^0.6.2"
63
63
  },
64
64
  "devDependencies": {
65
65
  "@bufbuild/buf": "^1.28.1",
package/proto/bsky.proto CHANGED
@@ -1194,7 +1194,8 @@ message PostsFilters {
1194
1194
  // Content filters
1195
1195
  repeated string domains = 3;
1196
1196
  repeated string urls = 4;
1197
- repeated string embed_uris = 5;
1197
+ // Canonical request field for posts embedding these AT-URI records.
1198
+ repeated string embedded_at_uris = 5;
1198
1199
  repeated string hashtags = 6;
1199
1200
  }
1200
1201
 
@@ -0,0 +1,235 @@
1
+ import { Timestamp } from '@bufbuild/protobuf'
2
+ import { mapDefined } from '@atproto/common'
3
+ import { AtUriString } from '@atproto/lex'
4
+ import { InvalidRequestError, Server } from '@atproto/xrpc-server'
5
+ import { AppContext } from '../../../../context.js'
6
+ import { DataPlaneClient } from '../../../../data-plane/index.js'
7
+ import {
8
+ PostSearchQuery,
9
+ parsePostSearchQuery,
10
+ } from '../../../../data-plane/server/util.js'
11
+ import { HydrateCtx, Hydrator } from '../../../../hydration/hydrator.js'
12
+ import { parseString } from '../../../../hydration/util.js'
13
+ import { app } from '../../../../lexicons/index.js'
14
+ import {
15
+ HydrationFnInput,
16
+ PresentationFnInput,
17
+ RulesFnInput,
18
+ SkeletonFnInput,
19
+ createPipeline,
20
+ } from '../../../../pipeline.js'
21
+ import {
22
+ SearchQueryLanguage,
23
+ SearchSortOrder,
24
+ } from '../../../../proto/bsky_pb.js'
25
+ import { uriToDid as creatorFromUri } from '../../../../util/uris.js'
26
+ import { Views } from '../../../../views/index.js'
27
+ import { resHeaders, resolveSearchV2Override } from '../../../util.js'
28
+
29
+ export default function (server: Server, ctx: AppContext) {
30
+ const searchPostsV2 = createPipeline(
31
+ skeleton,
32
+ hydration,
33
+ noBlocksOrTagged,
34
+ presentation,
35
+ )
36
+ server.add(app.bsky.feed.searchPostsV2, {
37
+ auth: ctx.authVerifier.standard,
38
+ handler: async ({ auth, params, req }) => {
39
+ const { viewer, isModService, skipViewerBlocks } =
40
+ ctx.authVerifier.parseCreds(auth)
41
+
42
+ const labelers = ctx.reqLabelers(req)
43
+ const hydrateCtx = await ctx.hydrator.createContext({
44
+ labelers,
45
+ viewer,
46
+ skipViewerBlocks,
47
+ features: ctx.featureGatesClient.scope(
48
+ ctx.featureGatesClient.parseUserContextFromHandler({
49
+ viewer,
50
+ req,
51
+ }),
52
+ ),
53
+ })
54
+ const isV2Enabled =
55
+ hydrateCtx.features.checkGate(
56
+ hydrateCtx.features.Gate.SearchV2Enable,
57
+ ) || resolveSearchV2Override(req, ctx.cfg)
58
+ if (!isV2Enabled) {
59
+ throw new InvalidRequestError('Search v2 is not enabled')
60
+ }
61
+
62
+ const results = await searchPostsV2(
63
+ {
64
+ ...params,
65
+ // Default to curated 'top' ranking when unset; the backend rejects an
66
+ // unspecified sort order.
67
+ sort: params.sort ?? 'top',
68
+ hydrateCtx,
69
+ isModService,
70
+ },
71
+ ctx,
72
+ )
73
+ return {
74
+ encoding: 'application/json',
75
+ body: results,
76
+ headers: resHeaders({ labelers: hydrateCtx.labelers }),
77
+ }
78
+ },
79
+ })
80
+ }
81
+
82
+ const skeleton = async (
83
+ inputs: SkeletonFnInput<Context, Params>,
84
+ ): Promise<Skeleton> => {
85
+ const { ctx, params } = inputs
86
+ const query = params.query ?? ''
87
+ const parsedQuery = parsePostSearchQuery(query, {
88
+ author: params.authors?.[0],
89
+ })
90
+
91
+ const res = await ctx.dataplane.searchPostsV2({
92
+ params: {
93
+ query,
94
+ viewer: params.hydrateCtx.viewer ?? undefined,
95
+ limit: params.limit,
96
+ cursor: params.cursor,
97
+ },
98
+ sort: postSortToV2(params.sort),
99
+ filters: {
100
+ authors: params.authors ?? [],
101
+ mentions: params.mentions ?? [],
102
+ domains: params.domains ?? [],
103
+ urls: params.urls ?? [],
104
+ embeddedAtUris: params.embeddedAtUris ?? [],
105
+ hashtags: params.hashtags ?? [],
106
+ },
107
+ exclude: {
108
+ authors: params.excludeAuthors ?? [],
109
+ mentions: params.excludeMentions ?? [],
110
+ domains: params.excludeDomains ?? [],
111
+ urls: params.excludeUrls ?? [],
112
+ embeddedAtUris: params.excludeEmbeddedAtUris ?? [],
113
+ hashtags: params.excludeHashtags ?? [],
114
+ },
115
+ since: parseTimestamp(params.since),
116
+ until: parseTimestamp(params.until),
117
+ allTime: params.allTime,
118
+ language: params.language,
119
+ hasMedia: params.hasMedia,
120
+ hasVideo: params.hasVideo,
121
+ replyParentUri: params.replyParentUri,
122
+ threadRootUri: params.threadRootUri,
123
+ excludeReplies: params.excludeReplies,
124
+ repliesOnly: params.repliesOnly,
125
+ following: params.following,
126
+ queryLanguage: queryLanguageToV2(params.queryLanguage),
127
+ })
128
+ return {
129
+ posts: res.posts.map(({ uri }) => uri as AtUriString),
130
+ cursor: parseString(res.pageInfo?.cursor),
131
+ hitsTotal: res.pageInfo?.hitsTotal
132
+ ? Number(res.pageInfo.hitsTotal)
133
+ : undefined,
134
+ detectedQueryLanguages: res.detectedQueryLanguages,
135
+ parsedQuery,
136
+ }
137
+ }
138
+
139
+ const hydration = async (
140
+ inputs: HydrationFnInput<Context, Params, Skeleton>,
141
+ ) => {
142
+ const { ctx, params, skeleton } = inputs
143
+ return ctx.hydrator.hydratePosts(
144
+ skeleton.posts.map((uri) => ({ uri })),
145
+ params.hydrateCtx,
146
+ )
147
+ }
148
+
149
+ const noBlocksOrTagged = (inputs: RulesFnInput<Context, Params, Skeleton>) => {
150
+ const { ctx, params, skeleton, hydration } = inputs
151
+ const { parsedQuery } = skeleton
152
+
153
+ skeleton.posts = skeleton.posts.filter((uri) => {
154
+ const post = hydration.posts?.get(uri)
155
+ if (!post) return
156
+
157
+ const creator = creatorFromUri(uri)
158
+ const isCuratedSearch = params.sort === 'top'
159
+ const isPostByViewer = creator === params.hydrateCtx.viewer
160
+
161
+ if (isPostByViewer) return true
162
+ if (params.isModService) return true
163
+
164
+ if (ctx.views.viewerBlockExists(creator, hydration)) return false
165
+
166
+ const tagged = [...ctx.cfg.searchTagsHide].some((t) => post.tags.has(t))
167
+
168
+ if (isCuratedSearch && tagged) return false
169
+ if (!(parsedQuery.author || params.authors?.length) && tagged) return false
170
+ return true
171
+ })
172
+ return skeleton
173
+ }
174
+
175
+ const presentation = (
176
+ inputs: PresentationFnInput<Context, Params, Skeleton>,
177
+ ) => {
178
+ const { ctx, skeleton, hydration } = inputs
179
+ const posts = mapDefined(skeleton.posts, (uri) => {
180
+ const post = hydration.posts?.get(uri)
181
+ if (!post) return
182
+
183
+ return ctx.views.post(uri, hydration)
184
+ })
185
+ return {
186
+ posts,
187
+ cursor: skeleton.cursor,
188
+ hitsTotal: skeleton.hitsTotal,
189
+ detectedQueryLanguages: skeleton.detectedQueryLanguages,
190
+ }
191
+ }
192
+
193
+ type Context = {
194
+ cfg: AppContext['cfg']
195
+ dataplane: DataPlaneClient
196
+ hydrator: Hydrator
197
+ views: Views
198
+ }
199
+
200
+ type Params = app.bsky.feed.searchPostsV2.$Params & {
201
+ hydrateCtx: HydrateCtx
202
+ isModService: boolean
203
+ }
204
+
205
+ type Skeleton = {
206
+ posts: AtUriString[]
207
+ hitsTotal?: number
208
+ cursor?: string
209
+ detectedQueryLanguages?: string[]
210
+ parsedQuery: PostSearchQuery
211
+ }
212
+
213
+ const postSortToV2 = (sort?: string): SearchSortOrder => {
214
+ if (sort === 'top') return SearchSortOrder.TOP
215
+ if (sort === 'recent') return SearchSortOrder.RECENT
216
+ return SearchSortOrder.UNSPECIFIED
217
+ }
218
+
219
+ const queryLanguageToV2 = (
220
+ lang: string | undefined,
221
+ ): SearchQueryLanguage | undefined => {
222
+ if (lang === 'ja') return SearchQueryLanguage.JA
223
+ if (lang === 'zh') return SearchQueryLanguage.ZH
224
+ if (lang === 'ko') return SearchQueryLanguage.KO
225
+ if (lang === 'th') return SearchQueryLanguage.TH
226
+ if (lang === 'ar') return SearchQueryLanguage.AR
227
+ return undefined
228
+ }
229
+
230
+ const parseTimestamp = (value: string | undefined): Timestamp | undefined => {
231
+ if (!value) return undefined
232
+ const date = new Date(value)
233
+ if (isNaN(date.getTime())) return undefined
234
+ return Timestamp.fromDate(date)
235
+ }
package/src/api/index.ts CHANGED
@@ -39,6 +39,7 @@ import getRepostedBy from './app/bsky/feed/getRepostedBy.js'
39
39
  import getSuggestedFeeds from './app/bsky/feed/getSuggestedFeeds.js'
40
40
  import getTimeline from './app/bsky/feed/getTimeline.js'
41
41
  import searchPosts from './app/bsky/feed/searchPosts.js'
42
+ import searchPostsV2 from './app/bsky/feed/searchPostsV2.js'
42
43
  import getActorStarterPacks from './app/bsky/graph/getActorStarterPacks.js'
43
44
  import getBlocks from './app/bsky/graph/getBlocks.js'
44
45
  import getFollowers from './app/bsky/graph/getFollowers.js'
@@ -142,6 +143,7 @@ export default function (server: Server, ctx: AppContext) {
142
143
  getPostThreadV2(server, ctx)
143
144
  getPosts(server, ctx)
144
145
  searchPosts(server, ctx)
146
+ searchPostsV2(server, ctx)
145
147
  getActorLikes(server, ctx)
146
148
  getProfile(server, ctx)
147
149
  getProfiles(server, ctx)
@@ -159,6 +159,7 @@ export default (db: Database): Partial<ServiceImpl<typeof Service>> => {
159
159
  return {
160
160
  posts: uris.map((uri) => ({ uri, score: 0 })),
161
161
  pageInfo: { cursor: cursor ?? '', hitsTotal: 0n },
162
+ detectedQueryLanguages: [],
162
163
  }
163
164
  },
164
165