@atproto/bsky 0.0.9 → 0.0.11
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 +20 -0
- package/dist/config.d.ts +2 -0
- package/dist/context.d.ts +3 -0
- package/dist/db/index.js +55 -3
- package/dist/db/index.js.map +3 -3
- package/dist/index.js +1125 -301
- package/dist/index.js.map +3 -3
- package/dist/lexicon/index.d.ts +14 -2
- package/dist/lexicon/lexicons.d.ts +302 -14
- package/dist/lexicon/types/app/bsky/actor/searchActors.d.ts +1 -0
- package/dist/lexicon/types/app/bsky/actor/searchActorsTypeahead.d.ts +1 -0
- package/dist/lexicon/types/app/bsky/feed/searchPosts.d.ts +37 -0
- package/dist/lexicon/types/app/bsky/unspecced/defs.d.ts +13 -0
- package/dist/lexicon/types/app/bsky/unspecced/searchActorsSkeleton.d.ts +38 -0
- package/dist/lexicon/types/app/bsky/unspecced/searchPostsSkeleton.d.ts +37 -0
- package/dist/lexicon/types/com/atproto/admin/searchRepos.d.ts +1 -0
- package/dist/lexicon/types/com/atproto/server/confirmEmail.d.ts +27 -0
- package/dist/lexicon/types/com/atproto/server/createSession.d.ts +1 -0
- package/dist/lexicon/types/com/atproto/server/getSession.d.ts +1 -0
- package/dist/lexicon/types/com/atproto/server/requestEmailConfirmation.d.ts +19 -0
- package/dist/lexicon/types/com/atproto/server/requestEmailUpdate.d.ts +30 -0
- package/dist/lexicon/types/{app/bsky/unspecced/applyLabels.d.ts → com/atproto/server/updateEmail.d.ts} +3 -2
- package/dist/services/actor/index.d.ts +2 -2
- package/dist/services/util/search.d.ts +3 -3
- package/package.json +13 -14
- package/src/api/app/bsky/actor/searchActors.ts +36 -16
- package/src/api/app/bsky/actor/searchActorsTypeahead.ts +24 -11
- package/src/api/app/bsky/graph/getSuggestedFollowsByActor.ts +1 -0
- package/src/api/com/atproto/admin/searchRepos.ts +6 -4
- package/src/auto-moderator/index.ts +1 -17
- package/src/config.ts +7 -0
- package/src/context.ts +6 -0
- package/src/index.ts +5 -0
- package/src/lexicon/index.ts +84 -12
- package/src/lexicon/lexicons.ts +351 -23
- package/src/lexicon/types/app/bsky/actor/searchActors.ts +3 -0
- package/src/lexicon/types/app/bsky/actor/searchActorsTypeahead.ts +3 -0
- package/src/lexicon/types/app/bsky/feed/searchPosts.ts +54 -0
- package/src/lexicon/types/app/bsky/unspecced/defs.ts +41 -0
- package/src/lexicon/types/app/bsky/unspecced/searchActorsSkeleton.ts +56 -0
- package/src/lexicon/types/app/bsky/unspecced/searchPostsSkeleton.ts +54 -0
- package/src/lexicon/types/com/atproto/admin/searchRepos.ts +2 -0
- package/src/lexicon/types/{app/bsky/unspecced/applyLabels.ts → com/atproto/server/confirmEmail.ts} +3 -2
- package/src/lexicon/types/com/atproto/server/createSession.ts +1 -0
- package/src/lexicon/types/com/atproto/server/getSession.ts +1 -0
- package/src/lexicon/types/com/atproto/server/requestEmailConfirmation.ts +31 -0
- package/src/lexicon/types/com/atproto/server/requestEmailUpdate.ts +43 -0
- package/src/lexicon/types/com/atproto/server/updateEmail.ts +41 -0
- package/src/services/actor/index.ts +9 -9
- package/src/services/indexing/plugins/block.ts +1 -1
- package/src/services/indexing/plugins/feed-generator.ts +1 -1
- package/src/services/indexing/plugins/follow.ts +1 -1
- package/src/services/indexing/plugins/like.ts +1 -1
- package/src/services/indexing/plugins/list-block.ts +1 -1
- package/src/services/indexing/plugins/list-item.ts +1 -1
- package/src/services/indexing/plugins/list.ts +1 -1
- package/src/services/indexing/plugins/post.ts +1 -1
- package/src/services/indexing/plugins/repost.ts +1 -1
- package/src/services/indexing/plugins/thread-gate.ts +1 -1
- package/src/services/label/index.ts +1 -1
- package/src/services/util/search.ts +24 -23
- package/dist/services/indexing/util.d.ts +0 -1
- package/src/services/indexing/util.ts +0 -16
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import express from 'express';
|
|
2
|
+
import { HandlerAuth } from '@atproto/xrpc-server';
|
|
3
|
+
import * as AppBskyUnspeccedDefs from './defs';
|
|
4
|
+
export interface QueryParams {
|
|
5
|
+
q: string;
|
|
6
|
+
typeahead?: boolean;
|
|
7
|
+
limit: number;
|
|
8
|
+
cursor?: string;
|
|
9
|
+
}
|
|
10
|
+
export declare type InputSchema = undefined;
|
|
11
|
+
export interface OutputSchema {
|
|
12
|
+
cursor?: string;
|
|
13
|
+
hitsTotal?: number;
|
|
14
|
+
actors: AppBskyUnspeccedDefs.SkeletonSearchActor[];
|
|
15
|
+
[k: string]: unknown;
|
|
16
|
+
}
|
|
17
|
+
export declare type HandlerInput = undefined;
|
|
18
|
+
export interface HandlerSuccess {
|
|
19
|
+
encoding: 'application/json';
|
|
20
|
+
body: OutputSchema;
|
|
21
|
+
headers?: {
|
|
22
|
+
[key: string]: string;
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
export interface HandlerError {
|
|
26
|
+
status: number;
|
|
27
|
+
message?: string;
|
|
28
|
+
error?: 'BadQueryString';
|
|
29
|
+
}
|
|
30
|
+
export declare type HandlerOutput = HandlerError | HandlerSuccess;
|
|
31
|
+
export declare type HandlerReqCtx<HA extends HandlerAuth = never> = {
|
|
32
|
+
auth: HA;
|
|
33
|
+
params: QueryParams;
|
|
34
|
+
input: HandlerInput;
|
|
35
|
+
req: express.Request;
|
|
36
|
+
res: express.Response;
|
|
37
|
+
};
|
|
38
|
+
export declare type Handler<HA extends HandlerAuth = never> = (ctx: HandlerReqCtx<HA>) => Promise<HandlerOutput> | HandlerOutput;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import express from 'express';
|
|
2
|
+
import { HandlerAuth } from '@atproto/xrpc-server';
|
|
3
|
+
import * as AppBskyUnspeccedDefs from './defs';
|
|
4
|
+
export interface QueryParams {
|
|
5
|
+
q: string;
|
|
6
|
+
limit: number;
|
|
7
|
+
cursor?: string;
|
|
8
|
+
}
|
|
9
|
+
export declare type InputSchema = undefined;
|
|
10
|
+
export interface OutputSchema {
|
|
11
|
+
cursor?: string;
|
|
12
|
+
hitsTotal?: number;
|
|
13
|
+
posts: AppBskyUnspeccedDefs.SkeletonSearchPost[];
|
|
14
|
+
[k: string]: unknown;
|
|
15
|
+
}
|
|
16
|
+
export declare type HandlerInput = undefined;
|
|
17
|
+
export interface HandlerSuccess {
|
|
18
|
+
encoding: 'application/json';
|
|
19
|
+
body: OutputSchema;
|
|
20
|
+
headers?: {
|
|
21
|
+
[key: string]: string;
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
export interface HandlerError {
|
|
25
|
+
status: number;
|
|
26
|
+
message?: string;
|
|
27
|
+
error?: 'BadQueryString';
|
|
28
|
+
}
|
|
29
|
+
export declare type HandlerOutput = HandlerError | HandlerSuccess;
|
|
30
|
+
export declare type HandlerReqCtx<HA extends HandlerAuth = never> = {
|
|
31
|
+
auth: HA;
|
|
32
|
+
params: QueryParams;
|
|
33
|
+
input: HandlerInput;
|
|
34
|
+
req: express.Request;
|
|
35
|
+
res: express.Response;
|
|
36
|
+
};
|
|
37
|
+
export declare type Handler<HA extends HandlerAuth = never> = (ctx: HandlerReqCtx<HA>) => Promise<HandlerOutput> | HandlerOutput;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import express from 'express';
|
|
2
|
+
import { HandlerAuth } from '@atproto/xrpc-server';
|
|
3
|
+
export interface QueryParams {
|
|
4
|
+
}
|
|
5
|
+
export interface InputSchema {
|
|
6
|
+
email: string;
|
|
7
|
+
token: string;
|
|
8
|
+
[k: string]: unknown;
|
|
9
|
+
}
|
|
10
|
+
export interface HandlerInput {
|
|
11
|
+
encoding: 'application/json';
|
|
12
|
+
body: InputSchema;
|
|
13
|
+
}
|
|
14
|
+
export interface HandlerError {
|
|
15
|
+
status: number;
|
|
16
|
+
message?: string;
|
|
17
|
+
error?: 'AccountNotFound' | 'ExpiredToken' | 'InvalidToken' | 'InvalidEmail';
|
|
18
|
+
}
|
|
19
|
+
export declare type HandlerOutput = HandlerError | void;
|
|
20
|
+
export declare type HandlerReqCtx<HA extends HandlerAuth = never> = {
|
|
21
|
+
auth: HA;
|
|
22
|
+
params: QueryParams;
|
|
23
|
+
input: HandlerInput;
|
|
24
|
+
req: express.Request;
|
|
25
|
+
res: express.Response;
|
|
26
|
+
};
|
|
27
|
+
export declare type Handler<HA extends HandlerAuth = never> = (ctx: HandlerReqCtx<HA>) => Promise<HandlerOutput> | HandlerOutput;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import express from 'express';
|
|
2
|
+
import { HandlerAuth } from '@atproto/xrpc-server';
|
|
3
|
+
export interface QueryParams {
|
|
4
|
+
}
|
|
5
|
+
export declare type InputSchema = undefined;
|
|
6
|
+
export declare type HandlerInput = undefined;
|
|
7
|
+
export interface HandlerError {
|
|
8
|
+
status: number;
|
|
9
|
+
message?: string;
|
|
10
|
+
}
|
|
11
|
+
export declare type HandlerOutput = HandlerError | void;
|
|
12
|
+
export declare type HandlerReqCtx<HA extends HandlerAuth = never> = {
|
|
13
|
+
auth: HA;
|
|
14
|
+
params: QueryParams;
|
|
15
|
+
input: HandlerInput;
|
|
16
|
+
req: express.Request;
|
|
17
|
+
res: express.Response;
|
|
18
|
+
};
|
|
19
|
+
export declare type Handler<HA extends HandlerAuth = never> = (ctx: HandlerReqCtx<HA>) => Promise<HandlerOutput> | HandlerOutput;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import express from 'express';
|
|
2
|
+
import { HandlerAuth } from '@atproto/xrpc-server';
|
|
3
|
+
export interface QueryParams {
|
|
4
|
+
}
|
|
5
|
+
export declare type InputSchema = undefined;
|
|
6
|
+
export interface OutputSchema {
|
|
7
|
+
tokenRequired: boolean;
|
|
8
|
+
[k: string]: unknown;
|
|
9
|
+
}
|
|
10
|
+
export declare type HandlerInput = undefined;
|
|
11
|
+
export interface HandlerSuccess {
|
|
12
|
+
encoding: 'application/json';
|
|
13
|
+
body: OutputSchema;
|
|
14
|
+
headers?: {
|
|
15
|
+
[key: string]: string;
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
export interface HandlerError {
|
|
19
|
+
status: number;
|
|
20
|
+
message?: string;
|
|
21
|
+
}
|
|
22
|
+
export declare type HandlerOutput = HandlerError | HandlerSuccess;
|
|
23
|
+
export declare type HandlerReqCtx<HA extends HandlerAuth = never> = {
|
|
24
|
+
auth: HA;
|
|
25
|
+
params: QueryParams;
|
|
26
|
+
input: HandlerInput;
|
|
27
|
+
req: express.Request;
|
|
28
|
+
res: express.Response;
|
|
29
|
+
};
|
|
30
|
+
export declare type Handler<HA extends HandlerAuth = never> = (ctx: HandlerReqCtx<HA>) => Promise<HandlerOutput> | HandlerOutput;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import express from 'express';
|
|
2
2
|
import { HandlerAuth } from '@atproto/xrpc-server';
|
|
3
|
-
import * as ComAtprotoLabelDefs from '../../../com/atproto/label/defs';
|
|
4
3
|
export interface QueryParams {
|
|
5
4
|
}
|
|
6
5
|
export interface InputSchema {
|
|
7
|
-
|
|
6
|
+
email: string;
|
|
7
|
+
token?: string;
|
|
8
8
|
[k: string]: unknown;
|
|
9
9
|
}
|
|
10
10
|
export interface HandlerInput {
|
|
@@ -14,6 +14,7 @@ export interface HandlerInput {
|
|
|
14
14
|
export interface HandlerError {
|
|
15
15
|
status: number;
|
|
16
16
|
message?: string;
|
|
17
|
+
error?: 'ExpiredToken' | 'InvalidToken' | 'TokenRequired';
|
|
17
18
|
}
|
|
18
19
|
export declare type HandlerOutput = HandlerError | void;
|
|
19
20
|
export declare type HandlerReqCtx<HA extends HandlerAuth = never> = {
|
|
@@ -15,10 +15,10 @@ export declare class ActorService {
|
|
|
15
15
|
getActorDid(handleOrDid: string): Promise<string | null>;
|
|
16
16
|
getActor(handleOrDid: string, includeSoftDeleted?: boolean): Promise<ActorResult | null>;
|
|
17
17
|
getActors(handleOrDids: string[], includeSoftDeleted?: boolean): Promise<ActorResult[]>;
|
|
18
|
-
getSearchResults({ cursor, limit,
|
|
18
|
+
getSearchResults({ cursor, limit, query, includeSoftDeleted, }: {
|
|
19
19
|
cursor?: string;
|
|
20
20
|
limit?: number;
|
|
21
|
-
|
|
21
|
+
query?: string;
|
|
22
22
|
includeSoftDeleted?: boolean;
|
|
23
23
|
}): Promise<{
|
|
24
24
|
results: Actor[];
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Database } from '../../db';
|
|
2
2
|
import { GenericKeyset } from '../../db/pagination';
|
|
3
3
|
export declare const getUserSearchQuery: (db: Database, opts: {
|
|
4
|
-
|
|
4
|
+
query: string;
|
|
5
5
|
limit: number;
|
|
6
6
|
cursor?: string;
|
|
7
7
|
includeSoftDeleted?: boolean;
|
|
@@ -10,13 +10,13 @@ export declare const getUserSearchQuery: (db: Database, opts: {
|
|
|
10
10
|
distance: number;
|
|
11
11
|
}, "results">>, "actor" | "results", {}>;
|
|
12
12
|
export declare const getUserSearchQuerySimple: (db: Database, opts: {
|
|
13
|
-
|
|
13
|
+
query: string;
|
|
14
14
|
limit: number;
|
|
15
15
|
}) => import("kysely").SelectQueryBuilder<import("kysely/dist/cjs/parser/table-parser").From<import("../../db/database-schema").DatabaseSchemaType, import("kysely").AliasedQueryBuilder<import("kysely/dist/cjs/parser/table-parser").From<import("../../db/database-schema").DatabaseSchemaType, import("kysely").AliasedQueryBuilder<import("kysely/dist/cjs/parser/table-parser").From<import("../../db/database-schema").DatabaseSchemaType, "actor">, "actor", import("kysely").Selection<import("kysely/dist/cjs/parser/table-parser").From<import("../../db/database-schema").DatabaseSchemaType, "actor">, "actor", import("kysely").AliasedRawBuilder<number, "distance"> | import("kysely").AliasedRawBuilder<unknown, "did">>, "accounts_and_profiles">>, "accounts_and_profiles", {
|
|
16
16
|
did: unknown;
|
|
17
17
|
distance: number;
|
|
18
18
|
}, "results">>, "actor" | "results", {}>;
|
|
19
|
-
export declare const
|
|
19
|
+
export declare const cleanQuery: (query: string) => string;
|
|
20
20
|
declare type Result = {
|
|
21
21
|
distance: number;
|
|
22
22
|
did: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atproto/bsky",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.11",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Reference implementation of app.bsky App View (Bluesky API)",
|
|
6
6
|
"keywords": [
|
|
@@ -27,7 +27,6 @@
|
|
|
27
27
|
"http-errors": "^2.0.0",
|
|
28
28
|
"http-terminator": "^3.2.0",
|
|
29
29
|
"ioredis": "^5.3.2",
|
|
30
|
-
"iso-datestring-validator": "^2.2.2",
|
|
31
30
|
"kysely": "^0.22.0",
|
|
32
31
|
"multiformats": "^9.9.0",
|
|
33
32
|
"p-queue": "^6.6.2",
|
|
@@ -37,14 +36,14 @@
|
|
|
37
36
|
"sharp": "^0.31.2",
|
|
38
37
|
"typed-emitter": "^2.1.0",
|
|
39
38
|
"uint8arrays": "3.0.0",
|
|
40
|
-
"@atproto/api": "^0.6.
|
|
41
|
-
"@atproto/common": "^0.3.
|
|
39
|
+
"@atproto/api": "^0.6.20",
|
|
40
|
+
"@atproto/common": "^0.3.1",
|
|
42
41
|
"@atproto/crypto": "^0.2.2",
|
|
43
|
-
"@atproto/syntax": "^0.1.
|
|
44
|
-
"@atproto/identity": "^0.2.
|
|
45
|
-
"@atproto/lexicon": "^0.2.
|
|
46
|
-
"@atproto/repo": "^0.3.
|
|
47
|
-
"@atproto/xrpc-server": "^0.3.
|
|
42
|
+
"@atproto/syntax": "^0.1.2",
|
|
43
|
+
"@atproto/identity": "^0.2.1",
|
|
44
|
+
"@atproto/lexicon": "^0.2.2",
|
|
45
|
+
"@atproto/repo": "^0.3.2",
|
|
46
|
+
"@atproto/xrpc-server": "^0.3.2"
|
|
48
47
|
},
|
|
49
48
|
"devDependencies": {
|
|
50
49
|
"@did-plc/server": "^0.0.1",
|
|
@@ -55,11 +54,11 @@
|
|
|
55
54
|
"@types/qs": "^6.9.7",
|
|
56
55
|
"@types/sharp": "^0.31.0",
|
|
57
56
|
"axios": "^0.27.2",
|
|
58
|
-
"@atproto/api": "^0.6.
|
|
59
|
-
"@atproto/dev-env": "^0.2.
|
|
60
|
-
"@atproto/lex-cli": "^0.2.
|
|
61
|
-
"@atproto/pds": "^0.1.
|
|
62
|
-
"@atproto/xrpc": "^0.3.
|
|
57
|
+
"@atproto/api": "^0.6.20",
|
|
58
|
+
"@atproto/dev-env": "^0.2.11",
|
|
59
|
+
"@atproto/lex-cli": "^0.2.2",
|
|
60
|
+
"@atproto/pds": "^0.1.20",
|
|
61
|
+
"@atproto/xrpc": "^0.3.2"
|
|
63
62
|
},
|
|
64
63
|
"scripts": {
|
|
65
64
|
"codegen": "lex gen-server ./src/lexicon ../../lexicons/com/atproto/*/* ../../lexicons/app/bsky/*/*",
|
|
@@ -2,7 +2,7 @@ import { sql } from 'kysely'
|
|
|
2
2
|
import AppContext from '../../../../context'
|
|
3
3
|
import { Server } from '../../../../lexicon'
|
|
4
4
|
import {
|
|
5
|
-
|
|
5
|
+
cleanQuery,
|
|
6
6
|
getUserSearchQuery,
|
|
7
7
|
SearchKeyset,
|
|
8
8
|
} from '../../../../services/util/search'
|
|
@@ -11,31 +11,51 @@ export default function (server: Server, ctx: AppContext) {
|
|
|
11
11
|
server.app.bsky.actor.searchActors({
|
|
12
12
|
auth: ctx.authOptionalVerifier,
|
|
13
13
|
handler: async ({ auth, params }) => {
|
|
14
|
-
const { cursor, limit
|
|
14
|
+
const { cursor, limit } = params
|
|
15
15
|
const requester = auth.credentials.did
|
|
16
|
-
const
|
|
17
|
-
|
|
16
|
+
const rawQuery = params.q ?? params.term
|
|
17
|
+
const query = cleanQuery(rawQuery || '')
|
|
18
18
|
const db = ctx.db.getReplica('search')
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
20
|
+
let results: string[]
|
|
21
|
+
let resCursor: string | undefined
|
|
22
|
+
if (ctx.searchAgent) {
|
|
23
|
+
const res =
|
|
24
|
+
await ctx.searchAgent.api.app.bsky.unspecced.searchActorsSkeleton({
|
|
25
|
+
q: query,
|
|
26
|
+
cursor,
|
|
27
|
+
limit,
|
|
28
|
+
})
|
|
29
|
+
results = res.data.actors.map((a) => a.did)
|
|
30
|
+
resCursor = res.data.cursor
|
|
31
|
+
} else {
|
|
32
|
+
const res = query
|
|
33
|
+
? await getUserSearchQuery(db, { query, limit, cursor })
|
|
34
|
+
.select('distance')
|
|
35
|
+
.selectAll('actor')
|
|
36
|
+
.execute()
|
|
37
|
+
: []
|
|
38
|
+
results = res.map((a) => a.did)
|
|
39
|
+
const keyset = new SearchKeyset(sql``, sql``)
|
|
40
|
+
resCursor = keyset.packFromResult(res)
|
|
41
|
+
}
|
|
27
42
|
|
|
28
43
|
const actors = await ctx.services
|
|
29
44
|
.actor(db)
|
|
30
|
-
.views.
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
)
|
|
45
|
+
.views.profiles(results, requester)
|
|
46
|
+
|
|
47
|
+
const SKIP = []
|
|
48
|
+
const filtered = results.flatMap((did) => {
|
|
49
|
+
const actor = actors[did]
|
|
50
|
+
if (!actor) return SKIP
|
|
51
|
+
if (actor.viewer?.blocking || actor.viewer?.blockedBy) return SKIP
|
|
52
|
+
return actor
|
|
53
|
+
})
|
|
34
54
|
|
|
35
55
|
return {
|
|
36
56
|
encoding: 'application/json',
|
|
37
57
|
body: {
|
|
38
|
-
cursor:
|
|
58
|
+
cursor: resCursor,
|
|
39
59
|
actors: filtered,
|
|
40
60
|
},
|
|
41
61
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import AppContext from '../../../../context'
|
|
2
2
|
import { Server } from '../../../../lexicon'
|
|
3
3
|
import {
|
|
4
|
-
|
|
4
|
+
cleanQuery,
|
|
5
5
|
getUserSearchQuerySimple,
|
|
6
6
|
} from '../../../../services/util/search'
|
|
7
7
|
|
|
@@ -9,25 +9,38 @@ export default function (server: Server, ctx: AppContext) {
|
|
|
9
9
|
server.app.bsky.actor.searchActorsTypeahead({
|
|
10
10
|
auth: ctx.authOptionalVerifier,
|
|
11
11
|
handler: async ({ params, auth }) => {
|
|
12
|
-
const { limit
|
|
12
|
+
const { limit } = params
|
|
13
13
|
const requester = auth.credentials.did
|
|
14
|
-
const
|
|
15
|
-
|
|
14
|
+
const rawQuery = params.q ?? params.term
|
|
15
|
+
const query = cleanQuery(rawQuery || '')
|
|
16
16
|
const db = ctx.db.getReplica('search')
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
18
|
+
let results: string[]
|
|
19
|
+
if (ctx.searchAgent) {
|
|
20
|
+
const res =
|
|
21
|
+
await ctx.searchAgent.api.app.bsky.unspecced.searchActorsSkeleton({
|
|
22
|
+
q: query,
|
|
23
|
+
typeahead: true,
|
|
24
|
+
limit,
|
|
25
|
+
})
|
|
26
|
+
results = res.data.actors.map((a) => a.did)
|
|
27
|
+
} else {
|
|
28
|
+
const res = query
|
|
29
|
+
? await getUserSearchQuerySimple(db, { query, limit })
|
|
30
|
+
.selectAll('actor')
|
|
31
|
+
.execute()
|
|
32
|
+
: []
|
|
33
|
+
results = res.map((a) => a.did)
|
|
34
|
+
}
|
|
23
35
|
|
|
24
36
|
const actors = await ctx.services
|
|
25
37
|
.actor(db)
|
|
26
38
|
.views.profilesBasic(results, requester, { omitLabels: true })
|
|
27
39
|
|
|
28
40
|
const SKIP = []
|
|
29
|
-
const filtered = results.flatMap((
|
|
30
|
-
const actor = actors[
|
|
41
|
+
const filtered = results.flatMap((did) => {
|
|
42
|
+
const actor = actors[did]
|
|
43
|
+
if (!actor) return SKIP
|
|
31
44
|
if (actor.viewer?.blocking || actor.viewer?.blockedBy) return SKIP
|
|
32
45
|
return actor
|
|
33
46
|
})
|
|
@@ -8,18 +8,20 @@ export default function (server: Server, ctx: AppContext) {
|
|
|
8
8
|
handler: async ({ params }) => {
|
|
9
9
|
const db = ctx.db.getPrimary()
|
|
10
10
|
const moderationService = ctx.services.moderation(db)
|
|
11
|
-
const { invitedBy } = params
|
|
11
|
+
const { invitedBy, limit, cursor } = params
|
|
12
12
|
if (invitedBy) {
|
|
13
13
|
throw new InvalidRequestError('The invitedBy parameter is unsupported')
|
|
14
14
|
}
|
|
15
|
+
// prefer new 'q' query param over deprecated 'term'
|
|
16
|
+
const query = params.q ?? params.term
|
|
15
17
|
|
|
16
|
-
const { results, cursor } = await ctx.services
|
|
18
|
+
const { results, cursor: resCursor } = await ctx.services
|
|
17
19
|
.actor(db)
|
|
18
|
-
.getSearchResults({
|
|
20
|
+
.getSearchResults({ query, limit, cursor, includeSoftDeleted: true })
|
|
19
21
|
return {
|
|
20
22
|
encoding: 'application/json',
|
|
21
23
|
body: {
|
|
22
|
-
cursor,
|
|
24
|
+
cursor: resCursor,
|
|
23
25
|
repos: await moderationService.views.repo(results),
|
|
24
26
|
},
|
|
25
27
|
}
|
|
@@ -280,28 +280,12 @@ export class AutoModerator {
|
|
|
280
280
|
async storeLabels(uri: AtUri, cid: CID, labels: string[]): Promise<void> {
|
|
281
281
|
if (labels.length < 1) return
|
|
282
282
|
const labelSrvc = this.services.label(this.ctx.db)
|
|
283
|
-
|
|
283
|
+
await labelSrvc.formatAndCreate(
|
|
284
284
|
this.ctx.cfg.labelerDid,
|
|
285
285
|
uri.toString(),
|
|
286
286
|
cid.toString(),
|
|
287
287
|
{ create: labels },
|
|
288
288
|
)
|
|
289
|
-
if (this.pushAgent) {
|
|
290
|
-
const agent = this.pushAgent
|
|
291
|
-
try {
|
|
292
|
-
await agent.api.app.bsky.unspecced.applyLabels({ labels: formatted })
|
|
293
|
-
} catch (err) {
|
|
294
|
-
log.error(
|
|
295
|
-
{
|
|
296
|
-
err,
|
|
297
|
-
uri: uri.toString(),
|
|
298
|
-
labels,
|
|
299
|
-
receiver: agent.service.toString(),
|
|
300
|
-
},
|
|
301
|
-
'failed to push labels',
|
|
302
|
-
)
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
289
|
}
|
|
306
290
|
|
|
307
291
|
async processAll() {
|
package/src/config.ts
CHANGED
|
@@ -18,6 +18,7 @@ export interface ServerConfigValues {
|
|
|
18
18
|
handleResolveNameservers?: string[]
|
|
19
19
|
imgUriEndpoint?: string
|
|
20
20
|
blobCacheLocation?: string
|
|
21
|
+
searchEndpoint?: string
|
|
21
22
|
labelerDid: string
|
|
22
23
|
adminPassword: string
|
|
23
24
|
moderatorPassword?: string
|
|
@@ -51,6 +52,7 @@ export class ServerConfig {
|
|
|
51
52
|
: []
|
|
52
53
|
const imgUriEndpoint = process.env.IMG_URI_ENDPOINT
|
|
53
54
|
const blobCacheLocation = process.env.BLOB_CACHE_LOC
|
|
55
|
+
const searchEndpoint = process.env.SEARCH_ENDPOINT
|
|
54
56
|
const dbPrimaryPostgresUrl =
|
|
55
57
|
overrides?.dbPrimaryPostgresUrl || process.env.DB_PRIMARY_POSTGRES_URL
|
|
56
58
|
let dbReplicaPostgresUrls = overrides?.dbReplicaPostgresUrls
|
|
@@ -97,6 +99,7 @@ export class ServerConfig {
|
|
|
97
99
|
handleResolveNameservers,
|
|
98
100
|
imgUriEndpoint,
|
|
99
101
|
blobCacheLocation,
|
|
102
|
+
searchEndpoint,
|
|
100
103
|
labelerDid,
|
|
101
104
|
adminPassword,
|
|
102
105
|
moderatorPassword,
|
|
@@ -183,6 +186,10 @@ export class ServerConfig {
|
|
|
183
186
|
return this.cfg.blobCacheLocation
|
|
184
187
|
}
|
|
185
188
|
|
|
189
|
+
get searchEndpoint() {
|
|
190
|
+
return this.cfg.searchEndpoint
|
|
191
|
+
}
|
|
192
|
+
|
|
186
193
|
get labelerDid() {
|
|
187
194
|
return this.cfg.labelerDid
|
|
188
195
|
}
|
package/src/context.ts
CHANGED
|
@@ -10,6 +10,7 @@ import { BackgroundQueue } from './background'
|
|
|
10
10
|
import { MountedAlgos } from './feed-gen/types'
|
|
11
11
|
import { LabelCache } from './label-cache'
|
|
12
12
|
import { NotificationServer } from './notifications'
|
|
13
|
+
import { AtpAgent } from '@atproto/api'
|
|
13
14
|
|
|
14
15
|
export class AppContext {
|
|
15
16
|
constructor(
|
|
@@ -22,6 +23,7 @@ export class AppContext {
|
|
|
22
23
|
didCache: DidSqlCache
|
|
23
24
|
labelCache: LabelCache
|
|
24
25
|
backgroundQueue: BackgroundQueue
|
|
26
|
+
searchAgent?: AtpAgent
|
|
25
27
|
algos: MountedAlgos
|
|
26
28
|
notifServer: NotificationServer
|
|
27
29
|
},
|
|
@@ -63,6 +65,10 @@ export class AppContext {
|
|
|
63
65
|
return this.opts.notifServer
|
|
64
66
|
}
|
|
65
67
|
|
|
68
|
+
get searchAgent(): AtpAgent | undefined {
|
|
69
|
+
return this.opts.searchAgent
|
|
70
|
+
}
|
|
71
|
+
|
|
66
72
|
get authVerifier() {
|
|
67
73
|
return auth.authVerifier(this.idResolver, { aud: this.cfg.serverDid })
|
|
68
74
|
}
|
package/src/index.ts
CHANGED
|
@@ -25,6 +25,7 @@ import { BackgroundQueue } from './background'
|
|
|
25
25
|
import { MountedAlgos } from './feed-gen/types'
|
|
26
26
|
import { LabelCache } from './label-cache'
|
|
27
27
|
import { NotificationServer } from './notifications'
|
|
28
|
+
import { AtpAgent } from '@atproto/api'
|
|
28
29
|
|
|
29
30
|
export type { ServerConfigValues } from './config'
|
|
30
31
|
export type { MountedAlgos } from './feed-gen/types'
|
|
@@ -100,6 +101,9 @@ export class BskyAppView {
|
|
|
100
101
|
const backgroundQueue = new BackgroundQueue(db.getPrimary())
|
|
101
102
|
const labelCache = new LabelCache(db.getPrimary())
|
|
102
103
|
const notifServer = new NotificationServer(db.getPrimary())
|
|
104
|
+
const searchAgent = config.searchEndpoint
|
|
105
|
+
? new AtpAgent({ service: config.searchEndpoint })
|
|
106
|
+
: undefined
|
|
103
107
|
|
|
104
108
|
const services = createServices({
|
|
105
109
|
imgUriBuilder,
|
|
@@ -116,6 +120,7 @@ export class BskyAppView {
|
|
|
116
120
|
didCache,
|
|
117
121
|
labelCache,
|
|
118
122
|
backgroundQueue,
|
|
123
|
+
searchAgent,
|
|
119
124
|
algos,
|
|
120
125
|
notifServer,
|
|
121
126
|
})
|