@atproto/bsky 0.0.256 → 0.0.257
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.
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# @atproto/bsky
|
|
2
2
|
|
|
3
|
+
## 0.0.257
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#5211](https://github.com/bluesky-social/atproto/pull/5211) [`68ed54d`](https://github.com/bluesky-social/atproto/commit/68ed54d875e10d0f1db52b8a4e5b191a5650d25b) Thanks [@estrattonbailey](https://github.com/estrattonbailey)! - Sanitize cursors in v1 searchPosts, throwing more specific error for downstream consumers
|
|
8
|
+
|
|
3
9
|
## 0.0.256
|
|
4
10
|
|
|
5
11
|
### Patch Changes
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type Server } from '@atproto/xrpc-server';
|
|
2
2
|
import type { AppContext } from '../../../../context.js';
|
|
3
3
|
export default function (server: Server, ctx: AppContext): void;
|
|
4
4
|
//# sourceMappingURL=searchPosts.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"searchPosts.d.ts","sourceRoot":"","sources":["../../../../../src/api/app/bsky/feed/searchPosts.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"searchPosts.d.ts","sourceRoot":"","sources":["../../../../../src/api/app/bsky/feed/searchPosts.ts"],"names":[],"mappings":"AAGA,OAAO,EAAuB,KAAK,MAAM,EAAE,MAAM,sBAAsB,CAAA;AAEvE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAqBxD,MAAM,CAAC,OAAO,WAAW,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,QAyCvD"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Timestamp } from '@bufbuild/protobuf';
|
|
2
2
|
import { mapDefined } from '@atproto/common';
|
|
3
|
+
import { InvalidRequestError } from '@atproto/xrpc-server';
|
|
3
4
|
import { parsePostSearchQuery, } from '../../../../data-plane/server/util.js';
|
|
4
5
|
import { parseString } from '../../../../hydration/util.js';
|
|
5
6
|
import { app } from '../../../../lexicons/index.js';
|
|
@@ -87,7 +88,7 @@ const skeletonV2 = async (inputs) => {
|
|
|
87
88
|
query: params.q,
|
|
88
89
|
viewer: params.hydrateCtx.viewer ?? undefined,
|
|
89
90
|
limit: params.limit,
|
|
90
|
-
cursor: params.cursor,
|
|
91
|
+
cursor: sanitizeCursor(params.cursor),
|
|
91
92
|
},
|
|
92
93
|
sort: postSortToV2(params.sort),
|
|
93
94
|
filters: {
|
|
@@ -199,4 +200,19 @@ const parseTimestamp = (value) => {
|
|
|
199
200
|
return undefined;
|
|
200
201
|
return Timestamp.fromDate(date);
|
|
201
202
|
};
|
|
203
|
+
const sanitizeCursor = (cursor) => {
|
|
204
|
+
if (!cursor)
|
|
205
|
+
return undefined;
|
|
206
|
+
try {
|
|
207
|
+
const decoded = Buffer.from(cursor, 'base64').toString('utf-8');
|
|
208
|
+
const parsed = JSON.parse(decoded);
|
|
209
|
+
if (typeof parsed === 'object' && parsed !== null) {
|
|
210
|
+
return cursor;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
catch {
|
|
214
|
+
// fall through to throw below
|
|
215
|
+
}
|
|
216
|
+
throw new InvalidRequestError('Invalid cursor format');
|
|
217
|
+
};
|
|
202
218
|
//# sourceMappingURL=searchPosts.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"searchPosts.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/feed/searchPosts.ts"],"names":[],"mappings":"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","sourcesContent":["import { Timestamp } from '@bufbuild/protobuf'\nimport { mapDefined } from '@atproto/common'\nimport type { AtUriString, Client } from '@atproto/lex'\nimport type { Server } from '@atproto/xrpc-server'\nimport type { ServerConfig } from '../../../../config.js'\nimport type { AppContext } from '../../../../context.js'\nimport type { DataPlaneClient } from '../../../../data-plane/index.js'\nimport {\n type PostSearchQuery,\n parsePostSearchQuery,\n} from '../../../../data-plane/server/util.js'\nimport type { HydrateCtx, Hydrator } from '../../../../hydration/hydrator.js'\nimport { parseString } from '../../../../hydration/util.js'\nimport { app } from '../../../../lexicons/index.js'\nimport {\n type HydrationFnInput,\n type PresentationFnInput,\n type RulesFnInput,\n type SkeletonFnInput,\n createPipeline,\n} from '../../../../pipeline.js'\nimport { SearchSortOrder } from '../../../../proto/bsky_pb.js'\nimport { uriToDid as creatorFromUri } from '../../../../util/uris.js'\nimport type { Views } from '../../../../views/index.js'\nimport { resHeaders, resolveSearchV2Override } from '../../../util.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const searchPosts = createPipeline(\n skeleton,\n hydration,\n noBlocksOrTagged,\n presentation,\n )\n server.add(app.bsky.feed.searchPosts, {\n auth: ctx.authVerifier.standardOptional,\n handler: async ({ auth, params, req }) => {\n const { viewer, isModService, skipViewerBlocks } =\n ctx.authVerifier.parseCreds(auth)\n\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({\n labelers,\n viewer,\n skipViewerBlocks,\n features: ctx.featureGatesClient.scope(\n ctx.featureGatesClient.parseUserContextFromHandler({\n viewer,\n req,\n }),\n ),\n })\n const results = await searchPosts(\n {\n ...params,\n hydrateCtx,\n isModService,\n isV2Override: resolveSearchV2Override(req, ctx.cfg),\n },\n ctx,\n )\n return {\n encoding: 'application/json',\n body: results,\n headers: resHeaders({ labelers: hydrateCtx.labelers }),\n }\n },\n })\n}\n\nconst skeletonV1 = async (\n inputs: SkeletonFnInput<Context, Params>,\n): Promise<Skeleton> => {\n const { ctx, params } = inputs\n const parsedQuery = parsePostSearchQuery(params.q, {\n author: params.author,\n })\n\n if (ctx.searchClient) {\n // @NOTE cursors won't change on appview swap\n const res = await ctx.searchClient.call(\n app.bsky.unspecced.searchPostsSkeleton,\n {\n q: params.q,\n cursor: params.cursor,\n limit: params.limit,\n author: params.author,\n domain: params.domain,\n lang: params.lang,\n mentions: params.mentions,\n since: params.since,\n sort: params.sort,\n tag: params.tag,\n until: params.until,\n url: params.url,\n viewer: params.hydrateCtx.viewer ?? undefined,\n },\n )\n return {\n posts: res.posts.map(({ uri }) => uri as AtUriString),\n cursor: parseString(res.cursor),\n parsedQuery,\n }\n }\n\n const res = await ctx.dataplane.searchPosts({\n term: params.q,\n limit: params.limit,\n cursor: params.cursor,\n })\n return {\n posts: res.uris as AtUriString[],\n cursor: parseString(res.cursor),\n parsedQuery,\n }\n}\n\nconst skeletonV2 = async (\n inputs: SkeletonFnInput<Context, Params>,\n): Promise<Skeleton> => {\n const { ctx, params } = inputs\n const parsedQuery = parsePostSearchQuery(params.q, {\n author: params.author,\n })\n const res = await ctx.dataplane.searchPostsV2({\n allTime: true, // match v1 behavior, v2 defaults to false\n params: {\n query: params.q,\n viewer: params.hydrateCtx.viewer ?? undefined,\n limit: params.limit,\n cursor: params.cursor,\n },\n sort: postSortToV2(params.sort),\n filters: {\n authors: params.author ? [params.author] : [],\n mentions: params.mentions ? [params.mentions] : [],\n domains: params.domain ? [params.domain] : [],\n urls: params.url ? [params.url] : [],\n hashtags: params.tag ?? [],\n languages: params.lang ? [params.lang] : [],\n },\n since: parseTimestamp(params.since),\n until: parseTimestamp(params.until),\n })\n return {\n posts: res.posts.map(({ uri }) => uri as AtUriString),\n cursor: parseString(res.pageInfo?.cursor),\n hitsTotal: res.pageInfo?.hitsTotal\n ? Number(res.pageInfo.hitsTotal)\n : undefined,\n parsedQuery,\n }\n}\n\nconst skeleton = async (input: SkeletonFnInput<Context, Params>) => {\n const useV2 =\n input.params.hydrateCtx.features.checkGate(\n input.params.hydrateCtx.features.Gate.SearchV2Enable,\n ) || input.params.isV2Override\n const skeletonFn = useV2 ? skeletonV2 : skeletonV1\n return skeletonFn(input)\n}\n\nconst hydration = async (\n inputs: HydrationFnInput<Context, Params, Skeleton>,\n) => {\n const { ctx, params, skeleton } = inputs\n return ctx.hydrator.hydratePosts(\n skeleton.posts.map((uri) => ({ uri })),\n params.hydrateCtx,\n undefined,\n {\n processDynamicTagsForView: params.hydrateCtx.features?.checkGate(\n params.hydrateCtx.features.Gate.SearchFilteringExplorationEnable,\n )\n ? 'search'\n : undefined,\n },\n )\n}\n\nconst noBlocksOrTagged = (inputs: RulesFnInput<Context, Params, Skeleton>) => {\n const { ctx, params, skeleton, hydration } = inputs\n const { parsedQuery } = skeleton\n\n skeleton.posts = skeleton.posts.filter((uri) => {\n const post = hydration.posts?.get(uri)\n if (!post) return\n\n const creator = creatorFromUri(uri)\n const isCuratedSearch = params.sort === 'top'\n const isPostByViewer = creator === params.hydrateCtx.viewer\n\n // Cases to always show.\n if (isPostByViewer) return true\n if (params.isModService) return true\n\n // Cases to never show.\n if (ctx.views.viewerBlockExists(creator, hydration)) return false\n\n // Roll the post's own tags together with moderation tags on its author,\n // so author-level tags are filtered the same way as post-level tags.\n const author = hydration.actors?.get(creator)\n const tags = new Set([\n ...post.tags,\n ...(author?.accountModerationTags ?? []),\n ...(author?.profileModerationTags ?? []),\n ])\n\n // Tags that are hidden from all search surfaces (Top and Latest),\n // regardless of curation or author filtering.\n const alwaysHidden = [...ctx.cfg.searchTagsHideAll].some((t) => tags.has(t))\n if (alwaysHidden) return false\n\n let tagged = false\n if (\n params.hydrateCtx.features?.checkGate(\n params.hydrateCtx.features.Gate.SearchFilteringExplorationEnable,\n )\n ) {\n tagged = tags.has(ctx.cfg.visibilityTagHide)\n } else {\n tagged = [...ctx.cfg.searchTagsHide].some((t) => tags.has(t))\n }\n\n // Cases to conditionally show based on tagging.\n if (isCuratedSearch && tagged) return false\n if (!parsedQuery.author && tagged) return false\n return true\n })\n return skeleton\n}\n\nconst presentation = (\n inputs: PresentationFnInput<Context, Params, Skeleton>,\n) => {\n const { ctx, skeleton, hydration } = inputs\n const posts = mapDefined(skeleton.posts, (uri) => {\n const post = hydration.posts?.get(uri)\n if (!post) return\n\n return ctx.views.post(uri, hydration)\n })\n return {\n posts,\n cursor: skeleton.cursor,\n hitsTotal: skeleton.hitsTotal,\n }\n}\n\ntype Context = {\n cfg: ServerConfig\n dataplane: DataPlaneClient\n hydrator: Hydrator\n views: Views\n searchClient?: Client\n}\n\ntype Params = app.bsky.feed.searchPosts.$Params & {\n hydrateCtx: HydrateCtx\n isModService: boolean\n isV2Override: boolean\n}\n\ntype Skeleton = {\n posts: AtUriString[]\n hitsTotal?: number\n cursor?: string\n parsedQuery: PostSearchQuery\n}\n\nconst postSortToV2 = (sort: string | undefined): SearchSortOrder => {\n if (sort === 'top') return SearchSortOrder.TOP\n if (sort === 'latest') return SearchSortOrder.RECENT\n return SearchSortOrder.UNSPECIFIED\n}\n\nconst parseTimestamp = (value: string | undefined): Timestamp | undefined => {\n if (!value) return undefined\n const date = new Date(value)\n if (isNaN(date.getTime())) return undefined\n return Timestamp.fromDate(date)\n}\n"]}
|
|
1
|
+
{"version":3,"file":"searchPosts.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/feed/searchPosts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAE5C,OAAO,EAAE,mBAAmB,EAAe,MAAM,sBAAsB,CAAA;AAIvE,OAAO,EAEL,oBAAoB,GACrB,MAAM,uCAAuC,CAAA;AAE9C,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAA;AAC3D,OAAO,EAAE,GAAG,EAAE,MAAM,+BAA+B,CAAA;AACnD,OAAO,EAKL,cAAc,GACf,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAA;AAC9D,OAAO,EAAE,QAAQ,IAAI,cAAc,EAAE,MAAM,0BAA0B,CAAA;AAErE,OAAO,EAAE,UAAU,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAA;AAEtE,MAAM,CAAC,OAAO,WAAW,MAAc,EAAE,GAAe;IACtD,MAAM,WAAW,GAAG,cAAc,CAChC,QAAQ,EACR,SAAS,EACT,gBAAgB,EAChB,YAAY,CACb,CAAA;IACD,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE;QACpC,IAAI,EAAE,GAAG,CAAC,YAAY,CAAC,gBAAgB;QACvC,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,EAAE;YACvC,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,gBAAgB,EAAE,GAC9C,GAAG,CAAC,YAAY,CAAC,UAAU,CAAC,IAAI,CAAC,CAAA;YAEnC,MAAM,QAAQ,GAAG,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAA;YACrC,MAAM,UAAU,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC,aAAa,CAAC;gBAClD,QAAQ;gBACR,MAAM;gBACN,gBAAgB;gBAChB,QAAQ,EAAE,GAAG,CAAC,kBAAkB,CAAC,KAAK,CACpC,GAAG,CAAC,kBAAkB,CAAC,2BAA2B,CAAC;oBACjD,MAAM;oBACN,GAAG;iBACJ,CAAC,CACH;aACF,CAAC,CAAA;YACF,MAAM,OAAO,GAAG,MAAM,WAAW,CAC/B;gBACE,GAAG,MAAM;gBACT,UAAU;gBACV,YAAY;gBACZ,YAAY,EAAE,uBAAuB,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,CAAC;aACpD,EACD,GAAG,CACJ,CAAA;YACD,OAAO;gBACL,QAAQ,EAAE,kBAAkB;gBAC5B,IAAI,EAAE,OAAO;gBACb,OAAO,EAAE,UAAU,CAAC,EAAE,QAAQ,EAAE,UAAU,CAAC,QAAQ,EAAE,CAAC;aACvD,CAAA;QACH,CAAC;KACF,CAAC,CAAA;AACJ,CAAC;AAED,MAAM,UAAU,GAAG,KAAK,EACtB,MAAwC,EACrB,EAAE;IACrB,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,MAAM,CAAA;IAC9B,MAAM,WAAW,GAAG,oBAAoB,CAAC,MAAM,CAAC,CAAC,EAAE;QACjD,MAAM,EAAE,MAAM,CAAC,MAAM;KACtB,CAAC,CAAA;IAEF,IAAI,GAAG,CAAC,YAAY,EAAE,CAAC;QACrB,6CAA6C;QAC7C,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,YAAY,CAAC,IAAI,CACrC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,mBAAmB,EACtC;YACE,CAAC,EAAE,MAAM,CAAC,CAAC;YACX,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,GAAG,EAAE,MAAM,CAAC,GAAG;YACf,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,GAAG,EAAE,MAAM,CAAC,GAAG;YACf,MAAM,EAAE,MAAM,CAAC,UAAU,CAAC,MAAM,IAAI,SAAS;SAC9C,CACF,CAAA;QACD,OAAO;YACL,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,GAAkB,CAAC;YACrD,MAAM,EAAE,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC;YAC/B,WAAW;SACZ,CAAA;IACH,CAAC;IAED,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,SAAS,CAAC,WAAW,CAAC;QAC1C,IAAI,EAAE,MAAM,CAAC,CAAC;QACd,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,MAAM,EAAE,MAAM,CAAC,MAAM;KACtB,CAAC,CAAA;IACF,OAAO;QACL,KAAK,EAAE,GAAG,CAAC,IAAqB;QAChC,MAAM,EAAE,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC;QAC/B,WAAW;KACZ,CAAA;AACH,CAAC,CAAA;AAED,MAAM,UAAU,GAAG,KAAK,EACtB,MAAwC,EACrB,EAAE;IACrB,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,MAAM,CAAA;IAC9B,MAAM,WAAW,GAAG,oBAAoB,CAAC,MAAM,CAAC,CAAC,EAAE;QACjD,MAAM,EAAE,MAAM,CAAC,MAAM;KACtB,CAAC,CAAA;IACF,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,SAAS,CAAC,aAAa,CAAC;QAC5C,OAAO,EAAE,IAAI,EAAE,0CAA0C;QACzD,MAAM,EAAE;YACN,KAAK,EAAE,MAAM,CAAC,CAAC;YACf,MAAM,EAAE,MAAM,CAAC,UAAU,CAAC,MAAM,IAAI,SAAS;YAC7C,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,MAAM,EAAE,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC;SACtC;QACD,IAAI,EAAE,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC;QAC/B,OAAO,EAAE;YACP,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE;YAC7C,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE;YAClD,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE;YAC7C,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE;YACpC,QAAQ,EAAE,MAAM,CAAC,GAAG,IAAI,EAAE;YAC1B,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE;SAC5C;QACD,KAAK,EAAE,cAAc,CAAC,MAAM,CAAC,KAAK,CAAC;QACnC,KAAK,EAAE,cAAc,CAAC,MAAM,CAAC,KAAK,CAAC;KACpC,CAAC,CAAA;IACF,OAAO;QACL,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,GAAkB,CAAC;QACrD,MAAM,EAAE,WAAW,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC;QACzC,SAAS,EAAE,GAAG,CAAC,QAAQ,EAAE,SAAS;YAChC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC;YAChC,CAAC,CAAC,SAAS;QACb,WAAW;KACZ,CAAA;AACH,CAAC,CAAA;AAED,MAAM,QAAQ,GAAG,KAAK,EAAE,KAAuC,EAAE,EAAE;IACjE,MAAM,KAAK,GACT,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,SAAS,CACxC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,cAAc,CACrD,IAAI,KAAK,CAAC,MAAM,CAAC,YAAY,CAAA;IAChC,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,CAAA;IAClD,OAAO,UAAU,CAAC,KAAK,CAAC,CAAA;AAC1B,CAAC,CAAA;AAED,MAAM,SAAS,GAAG,KAAK,EACrB,MAAmD,EACnD,EAAE;IACF,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAA;IACxC,OAAO,GAAG,CAAC,QAAQ,CAAC,YAAY,CAC9B,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,EACtC,MAAM,CAAC,UAAU,EACjB,SAAS,EACT;QACE,yBAAyB,EAAE,MAAM,CAAC,UAAU,CAAC,QAAQ,EAAE,SAAS,CAC9D,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,gCAAgC,CACjE;YACC,CAAC,CAAC,QAAQ;YACV,CAAC,CAAC,SAAS;KACd,CACF,CAAA;AACH,CAAC,CAAA;AAED,MAAM,gBAAgB,GAAG,CAAC,MAA+C,EAAE,EAAE;IAC3E,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,MAAM,CAAA;IACnD,MAAM,EAAE,WAAW,EAAE,GAAG,QAAQ,CAAA;IAEhC,QAAQ,CAAC,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE;QAC7C,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,EAAE,GAAG,CAAC,GAAG,CAAC,CAAA;QACtC,IAAI,CAAC,IAAI;YAAE,OAAM;QAEjB,MAAM,OAAO,GAAG,cAAc,CAAC,GAAG,CAAC,CAAA;QACnC,MAAM,eAAe,GAAG,MAAM,CAAC,IAAI,KAAK,KAAK,CAAA;QAC7C,MAAM,cAAc,GAAG,OAAO,KAAK,MAAM,CAAC,UAAU,CAAC,MAAM,CAAA;QAE3D,wBAAwB;QACxB,IAAI,cAAc;YAAE,OAAO,IAAI,CAAA;QAC/B,IAAI,MAAM,CAAC,YAAY;YAAE,OAAO,IAAI,CAAA;QAEpC,uBAAuB;QACvB,IAAI,GAAG,CAAC,KAAK,CAAC,iBAAiB,CAAC,OAAO,EAAE,SAAS,CAAC;YAAE,OAAO,KAAK,CAAA;QAEjE,wEAAwE;QACxE,qEAAqE;QACrE,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;QAC7C,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC;YACnB,GAAG,IAAI,CAAC,IAAI;YACZ,GAAG,CAAC,MAAM,EAAE,qBAAqB,IAAI,EAAE,CAAC;YACxC,GAAG,CAAC,MAAM,EAAE,qBAAqB,IAAI,EAAE,CAAC;SACzC,CAAC,CAAA;QAEF,kEAAkE;QAClE,8CAA8C;QAC9C,MAAM,YAAY,GAAG,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAA;QAC5E,IAAI,YAAY;YAAE,OAAO,KAAK,CAAA;QAE9B,IAAI,MAAM,GAAG,KAAK,CAAA;QAClB,IACE,MAAM,CAAC,UAAU,CAAC,QAAQ,EAAE,SAAS,CACnC,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,gCAAgC,CACjE,EACD,CAAC;YACD,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAA;QAC9C,CAAC;aAAM,CAAC;YACN,MAAM,GAAG,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAA;QAC/D,CAAC;QAED,gDAAgD;QAChD,IAAI,eAAe,IAAI,MAAM;YAAE,OAAO,KAAK,CAAA;QAC3C,IAAI,CAAC,WAAW,CAAC,MAAM,IAAI,MAAM;YAAE,OAAO,KAAK,CAAA;QAC/C,OAAO,IAAI,CAAA;IACb,CAAC,CAAC,CAAA;IACF,OAAO,QAAQ,CAAA;AACjB,CAAC,CAAA;AAED,MAAM,YAAY,GAAG,CACnB,MAAsD,EACtD,EAAE;IACF,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,MAAM,CAAA;IAC3C,MAAM,KAAK,GAAG,UAAU,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,GAAG,EAAE,EAAE;QAC/C,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,EAAE,GAAG,CAAC,GAAG,CAAC,CAAA;QACtC,IAAI,CAAC,IAAI;YAAE,OAAM;QAEjB,OAAO,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAA;IACvC,CAAC,CAAC,CAAA;IACF,OAAO;QACL,KAAK;QACL,MAAM,EAAE,QAAQ,CAAC,MAAM;QACvB,SAAS,EAAE,QAAQ,CAAC,SAAS;KAC9B,CAAA;AACH,CAAC,CAAA;AAuBD,MAAM,YAAY,GAAG,CAAC,IAAwB,EAAmB,EAAE;IACjE,IAAI,IAAI,KAAK,KAAK;QAAE,OAAO,eAAe,CAAC,GAAG,CAAA;IAC9C,IAAI,IAAI,KAAK,QAAQ;QAAE,OAAO,eAAe,CAAC,MAAM,CAAA;IACpD,OAAO,eAAe,CAAC,WAAW,CAAA;AACpC,CAAC,CAAA;AAED,MAAM,cAAc,GAAG,CAAC,KAAyB,EAAyB,EAAE;IAC1E,IAAI,CAAC,KAAK;QAAE,OAAO,SAAS,CAAA;IAC5B,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,CAAA;IAC5B,IAAI,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;QAAE,OAAO,SAAS,CAAA;IAC3C,OAAO,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAA;AACjC,CAAC,CAAA;AAED,MAAM,cAAc,GAAG,CAAC,MAA0B,EAAsB,EAAE;IACxE,IAAI,CAAC,MAAM;QAAE,OAAO,SAAS,CAAA;IAC7B,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;QAC/D,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;QAClC,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;YAClD,OAAO,MAAM,CAAA;QACf,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,8BAA8B;IAChC,CAAC;IACD,MAAM,IAAI,mBAAmB,CAAC,uBAAuB,CAAC,CAAA;AACxD,CAAC,CAAA","sourcesContent":["import { Timestamp } from '@bufbuild/protobuf'\nimport { mapDefined } from '@atproto/common'\nimport type { AtUriString, Client } from '@atproto/lex'\nimport { InvalidRequestError, type Server } from '@atproto/xrpc-server'\nimport type { ServerConfig } from '../../../../config.js'\nimport type { AppContext } from '../../../../context.js'\nimport type { DataPlaneClient } from '../../../../data-plane/index.js'\nimport {\n type PostSearchQuery,\n parsePostSearchQuery,\n} from '../../../../data-plane/server/util.js'\nimport type { HydrateCtx, Hydrator } from '../../../../hydration/hydrator.js'\nimport { parseString } from '../../../../hydration/util.js'\nimport { app } from '../../../../lexicons/index.js'\nimport {\n type HydrationFnInput,\n type PresentationFnInput,\n type RulesFnInput,\n type SkeletonFnInput,\n createPipeline,\n} from '../../../../pipeline.js'\nimport { SearchSortOrder } from '../../../../proto/bsky_pb.js'\nimport { uriToDid as creatorFromUri } from '../../../../util/uris.js'\nimport type { Views } from '../../../../views/index.js'\nimport { resHeaders, resolveSearchV2Override } from '../../../util.js'\n\nexport default function (server: Server, ctx: AppContext) {\n const searchPosts = createPipeline(\n skeleton,\n hydration,\n noBlocksOrTagged,\n presentation,\n )\n server.add(app.bsky.feed.searchPosts, {\n auth: ctx.authVerifier.standardOptional,\n handler: async ({ auth, params, req }) => {\n const { viewer, isModService, skipViewerBlocks } =\n ctx.authVerifier.parseCreds(auth)\n\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({\n labelers,\n viewer,\n skipViewerBlocks,\n features: ctx.featureGatesClient.scope(\n ctx.featureGatesClient.parseUserContextFromHandler({\n viewer,\n req,\n }),\n ),\n })\n const results = await searchPosts(\n {\n ...params,\n hydrateCtx,\n isModService,\n isV2Override: resolveSearchV2Override(req, ctx.cfg),\n },\n ctx,\n )\n return {\n encoding: 'application/json',\n body: results,\n headers: resHeaders({ labelers: hydrateCtx.labelers }),\n }\n },\n })\n}\n\nconst skeletonV1 = async (\n inputs: SkeletonFnInput<Context, Params>,\n): Promise<Skeleton> => {\n const { ctx, params } = inputs\n const parsedQuery = parsePostSearchQuery(params.q, {\n author: params.author,\n })\n\n if (ctx.searchClient) {\n // @NOTE cursors won't change on appview swap\n const res = await ctx.searchClient.call(\n app.bsky.unspecced.searchPostsSkeleton,\n {\n q: params.q,\n cursor: params.cursor,\n limit: params.limit,\n author: params.author,\n domain: params.domain,\n lang: params.lang,\n mentions: params.mentions,\n since: params.since,\n sort: params.sort,\n tag: params.tag,\n until: params.until,\n url: params.url,\n viewer: params.hydrateCtx.viewer ?? undefined,\n },\n )\n return {\n posts: res.posts.map(({ uri }) => uri as AtUriString),\n cursor: parseString(res.cursor),\n parsedQuery,\n }\n }\n\n const res = await ctx.dataplane.searchPosts({\n term: params.q,\n limit: params.limit,\n cursor: params.cursor,\n })\n return {\n posts: res.uris as AtUriString[],\n cursor: parseString(res.cursor),\n parsedQuery,\n }\n}\n\nconst skeletonV2 = async (\n inputs: SkeletonFnInput<Context, Params>,\n): Promise<Skeleton> => {\n const { ctx, params } = inputs\n const parsedQuery = parsePostSearchQuery(params.q, {\n author: params.author,\n })\n const res = await ctx.dataplane.searchPostsV2({\n allTime: true, // match v1 behavior, v2 defaults to false\n params: {\n query: params.q,\n viewer: params.hydrateCtx.viewer ?? undefined,\n limit: params.limit,\n cursor: sanitizeCursor(params.cursor),\n },\n sort: postSortToV2(params.sort),\n filters: {\n authors: params.author ? [params.author] : [],\n mentions: params.mentions ? [params.mentions] : [],\n domains: params.domain ? [params.domain] : [],\n urls: params.url ? [params.url] : [],\n hashtags: params.tag ?? [],\n languages: params.lang ? [params.lang] : [],\n },\n since: parseTimestamp(params.since),\n until: parseTimestamp(params.until),\n })\n return {\n posts: res.posts.map(({ uri }) => uri as AtUriString),\n cursor: parseString(res.pageInfo?.cursor),\n hitsTotal: res.pageInfo?.hitsTotal\n ? Number(res.pageInfo.hitsTotal)\n : undefined,\n parsedQuery,\n }\n}\n\nconst skeleton = async (input: SkeletonFnInput<Context, Params>) => {\n const useV2 =\n input.params.hydrateCtx.features.checkGate(\n input.params.hydrateCtx.features.Gate.SearchV2Enable,\n ) || input.params.isV2Override\n const skeletonFn = useV2 ? skeletonV2 : skeletonV1\n return skeletonFn(input)\n}\n\nconst hydration = async (\n inputs: HydrationFnInput<Context, Params, Skeleton>,\n) => {\n const { ctx, params, skeleton } = inputs\n return ctx.hydrator.hydratePosts(\n skeleton.posts.map((uri) => ({ uri })),\n params.hydrateCtx,\n undefined,\n {\n processDynamicTagsForView: params.hydrateCtx.features?.checkGate(\n params.hydrateCtx.features.Gate.SearchFilteringExplorationEnable,\n )\n ? 'search'\n : undefined,\n },\n )\n}\n\nconst noBlocksOrTagged = (inputs: RulesFnInput<Context, Params, Skeleton>) => {\n const { ctx, params, skeleton, hydration } = inputs\n const { parsedQuery } = skeleton\n\n skeleton.posts = skeleton.posts.filter((uri) => {\n const post = hydration.posts?.get(uri)\n if (!post) return\n\n const creator = creatorFromUri(uri)\n const isCuratedSearch = params.sort === 'top'\n const isPostByViewer = creator === params.hydrateCtx.viewer\n\n // Cases to always show.\n if (isPostByViewer) return true\n if (params.isModService) return true\n\n // Cases to never show.\n if (ctx.views.viewerBlockExists(creator, hydration)) return false\n\n // Roll the post's own tags together with moderation tags on its author,\n // so author-level tags are filtered the same way as post-level tags.\n const author = hydration.actors?.get(creator)\n const tags = new Set([\n ...post.tags,\n ...(author?.accountModerationTags ?? []),\n ...(author?.profileModerationTags ?? []),\n ])\n\n // Tags that are hidden from all search surfaces (Top and Latest),\n // regardless of curation or author filtering.\n const alwaysHidden = [...ctx.cfg.searchTagsHideAll].some((t) => tags.has(t))\n if (alwaysHidden) return false\n\n let tagged = false\n if (\n params.hydrateCtx.features?.checkGate(\n params.hydrateCtx.features.Gate.SearchFilteringExplorationEnable,\n )\n ) {\n tagged = tags.has(ctx.cfg.visibilityTagHide)\n } else {\n tagged = [...ctx.cfg.searchTagsHide].some((t) => tags.has(t))\n }\n\n // Cases to conditionally show based on tagging.\n if (isCuratedSearch && tagged) return false\n if (!parsedQuery.author && tagged) return false\n return true\n })\n return skeleton\n}\n\nconst presentation = (\n inputs: PresentationFnInput<Context, Params, Skeleton>,\n) => {\n const { ctx, skeleton, hydration } = inputs\n const posts = mapDefined(skeleton.posts, (uri) => {\n const post = hydration.posts?.get(uri)\n if (!post) return\n\n return ctx.views.post(uri, hydration)\n })\n return {\n posts,\n cursor: skeleton.cursor,\n hitsTotal: skeleton.hitsTotal,\n }\n}\n\ntype Context = {\n cfg: ServerConfig\n dataplane: DataPlaneClient\n hydrator: Hydrator\n views: Views\n searchClient?: Client\n}\n\ntype Params = app.bsky.feed.searchPosts.$Params & {\n hydrateCtx: HydrateCtx\n isModService: boolean\n isV2Override: boolean\n}\n\ntype Skeleton = {\n posts: AtUriString[]\n hitsTotal?: number\n cursor?: string\n parsedQuery: PostSearchQuery\n}\n\nconst postSortToV2 = (sort: string | undefined): SearchSortOrder => {\n if (sort === 'top') return SearchSortOrder.TOP\n if (sort === 'latest') return SearchSortOrder.RECENT\n return SearchSortOrder.UNSPECIFIED\n}\n\nconst parseTimestamp = (value: string | undefined): Timestamp | undefined => {\n if (!value) return undefined\n const date = new Date(value)\n if (isNaN(date.getTime())) return undefined\n return Timestamp.fromDate(date)\n}\n\nconst sanitizeCursor = (cursor: string | undefined): string | undefined => {\n if (!cursor) return undefined\n try {\n const decoded = Buffer.from(cursor, 'base64').toString('utf-8')\n const parsed = JSON.parse(decoded)\n if (typeof parsed === 'object' && parsed !== null) {\n return cursor\n }\n } catch {\n // fall through to throw below\n }\n throw new InvalidRequestError('Invalid cursor format')\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atproto/bsky",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.257",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Reference implementation of app.bsky App View (Bluesky API)",
|
|
6
6
|
"keywords": [
|
|
@@ -60,18 +60,18 @@
|
|
|
60
60
|
"uint8arrays": "^5.0.0",
|
|
61
61
|
"undici": "^8.5.0",
|
|
62
62
|
"zod": "3.23.8",
|
|
63
|
-
"@atproto-labs/fetch-node": "^0.3.5",
|
|
64
63
|
"@atproto-labs/xrpc-utils": "^0.1.7",
|
|
64
|
+
"@atproto-labs/fetch-node": "^0.3.5",
|
|
65
65
|
"@atproto/api": "^0.20.27",
|
|
66
|
-
"@atproto/
|
|
66
|
+
"@atproto/common": "^0.7.1",
|
|
67
67
|
"@atproto/did": "^0.5.4",
|
|
68
68
|
"@atproto/identity": "^0.5.5",
|
|
69
|
-
"@atproto/
|
|
69
|
+
"@atproto/crypto": "^0.5.4",
|
|
70
70
|
"@atproto/lex": "^0.2.1",
|
|
71
|
-
"@atproto/sync": "^0.3.9",
|
|
72
71
|
"@atproto/repo": "^0.10.5",
|
|
73
|
-
"@atproto/
|
|
74
|
-
"@atproto/xrpc-server": "^0.11.8"
|
|
72
|
+
"@atproto/sync": "^0.3.9",
|
|
73
|
+
"@atproto/xrpc-server": "^0.11.8",
|
|
74
|
+
"@atproto/syntax": "^0.7.1"
|
|
75
75
|
},
|
|
76
76
|
"devDependencies": {
|
|
77
77
|
"@bufbuild/buf": "^1.28.1",
|