@atproto/bsky 0.0.10 → 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 +13 -0
- package/dist/config.d.ts +2 -0
- package/dist/context.d.ts +3 -0
- package/dist/db/index.js.map +1 -1
- package/dist/index.js +592 -205
- package/dist/index.js.map +3 -3
- package/dist/lexicon/index.d.ts +8 -0
- package/dist/lexicon/lexicons.d.ts +99 -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/com/atproto/server/updateEmail.d.ts +27 -0
- package/dist/services/actor/index.d.ts +2 -2
- package/dist/services/util/search.d.ts +3 -3
- package/package.json +13 -13
- package/src/api/app/bsky/actor/searchActors.ts +36 -22
- package/src/api/app/bsky/actor/searchActorsTypeahead.ts +24 -17
- package/src/api/app/bsky/graph/getSuggestedFollowsByActor.ts +1 -0
- package/src/api/com/atproto/admin/searchRepos.ts +5 -8
- package/src/config.ts +7 -0
- package/src/context.ts +6 -0
- package/src/index.ts +5 -0
- package/src/lexicon/index.ts +48 -0
- package/src/lexicon/lexicons.ts +122 -0
- package/src/lexicon/types/com/atproto/server/confirmEmail.ts +40 -0
- 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/util/search.ts +24 -23
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
|
})
|
package/src/lexicon/index.ts
CHANGED
|
@@ -39,6 +39,7 @@ import * as ComAtprotoRepoGetRecord from './types/com/atproto/repo/getRecord'
|
|
|
39
39
|
import * as ComAtprotoRepoListRecords from './types/com/atproto/repo/listRecords'
|
|
40
40
|
import * as ComAtprotoRepoPutRecord from './types/com/atproto/repo/putRecord'
|
|
41
41
|
import * as ComAtprotoRepoUploadBlob from './types/com/atproto/repo/uploadBlob'
|
|
42
|
+
import * as ComAtprotoServerConfirmEmail from './types/com/atproto/server/confirmEmail'
|
|
42
43
|
import * as ComAtprotoServerCreateAccount from './types/com/atproto/server/createAccount'
|
|
43
44
|
import * as ComAtprotoServerCreateAppPassword from './types/com/atproto/server/createAppPassword'
|
|
44
45
|
import * as ComAtprotoServerCreateInviteCode from './types/com/atproto/server/createInviteCode'
|
|
@@ -52,9 +53,12 @@ import * as ComAtprotoServerGetSession from './types/com/atproto/server/getSessi
|
|
|
52
53
|
import * as ComAtprotoServerListAppPasswords from './types/com/atproto/server/listAppPasswords'
|
|
53
54
|
import * as ComAtprotoServerRefreshSession from './types/com/atproto/server/refreshSession'
|
|
54
55
|
import * as ComAtprotoServerRequestAccountDelete from './types/com/atproto/server/requestAccountDelete'
|
|
56
|
+
import * as ComAtprotoServerRequestEmailConfirmation from './types/com/atproto/server/requestEmailConfirmation'
|
|
57
|
+
import * as ComAtprotoServerRequestEmailUpdate from './types/com/atproto/server/requestEmailUpdate'
|
|
55
58
|
import * as ComAtprotoServerRequestPasswordReset from './types/com/atproto/server/requestPasswordReset'
|
|
56
59
|
import * as ComAtprotoServerResetPassword from './types/com/atproto/server/resetPassword'
|
|
57
60
|
import * as ComAtprotoServerRevokeAppPassword from './types/com/atproto/server/revokeAppPassword'
|
|
61
|
+
import * as ComAtprotoServerUpdateEmail from './types/com/atproto/server/updateEmail'
|
|
58
62
|
import * as ComAtprotoSyncGetBlob from './types/com/atproto/sync/getBlob'
|
|
59
63
|
import * as ComAtprotoSyncGetBlocks from './types/com/atproto/sync/getBlocks'
|
|
60
64
|
import * as ComAtprotoSyncGetCheckout from './types/com/atproto/sync/getCheckout'
|
|
@@ -557,6 +561,17 @@ export class ServerNS {
|
|
|
557
561
|
this._server = server
|
|
558
562
|
}
|
|
559
563
|
|
|
564
|
+
confirmEmail<AV extends AuthVerifier>(
|
|
565
|
+
cfg: ConfigOf<
|
|
566
|
+
AV,
|
|
567
|
+
ComAtprotoServerConfirmEmail.Handler<ExtractAuth<AV>>,
|
|
568
|
+
ComAtprotoServerConfirmEmail.HandlerReqCtx<ExtractAuth<AV>>
|
|
569
|
+
>,
|
|
570
|
+
) {
|
|
571
|
+
const nsid = 'com.atproto.server.confirmEmail' // @ts-ignore
|
|
572
|
+
return this._server.xrpc.method(nsid, cfg)
|
|
573
|
+
}
|
|
574
|
+
|
|
560
575
|
createAccount<AV extends AuthVerifier>(
|
|
561
576
|
cfg: ConfigOf<
|
|
562
577
|
AV,
|
|
@@ -700,6 +715,28 @@ export class ServerNS {
|
|
|
700
715
|
return this._server.xrpc.method(nsid, cfg)
|
|
701
716
|
}
|
|
702
717
|
|
|
718
|
+
requestEmailConfirmation<AV extends AuthVerifier>(
|
|
719
|
+
cfg: ConfigOf<
|
|
720
|
+
AV,
|
|
721
|
+
ComAtprotoServerRequestEmailConfirmation.Handler<ExtractAuth<AV>>,
|
|
722
|
+
ComAtprotoServerRequestEmailConfirmation.HandlerReqCtx<ExtractAuth<AV>>
|
|
723
|
+
>,
|
|
724
|
+
) {
|
|
725
|
+
const nsid = 'com.atproto.server.requestEmailConfirmation' // @ts-ignore
|
|
726
|
+
return this._server.xrpc.method(nsid, cfg)
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
requestEmailUpdate<AV extends AuthVerifier>(
|
|
730
|
+
cfg: ConfigOf<
|
|
731
|
+
AV,
|
|
732
|
+
ComAtprotoServerRequestEmailUpdate.Handler<ExtractAuth<AV>>,
|
|
733
|
+
ComAtprotoServerRequestEmailUpdate.HandlerReqCtx<ExtractAuth<AV>>
|
|
734
|
+
>,
|
|
735
|
+
) {
|
|
736
|
+
const nsid = 'com.atproto.server.requestEmailUpdate' // @ts-ignore
|
|
737
|
+
return this._server.xrpc.method(nsid, cfg)
|
|
738
|
+
}
|
|
739
|
+
|
|
703
740
|
requestPasswordReset<AV extends AuthVerifier>(
|
|
704
741
|
cfg: ConfigOf<
|
|
705
742
|
AV,
|
|
@@ -732,6 +769,17 @@ export class ServerNS {
|
|
|
732
769
|
const nsid = 'com.atproto.server.revokeAppPassword' // @ts-ignore
|
|
733
770
|
return this._server.xrpc.method(nsid, cfg)
|
|
734
771
|
}
|
|
772
|
+
|
|
773
|
+
updateEmail<AV extends AuthVerifier>(
|
|
774
|
+
cfg: ConfigOf<
|
|
775
|
+
AV,
|
|
776
|
+
ComAtprotoServerUpdateEmail.Handler<ExtractAuth<AV>>,
|
|
777
|
+
ComAtprotoServerUpdateEmail.HandlerReqCtx<ExtractAuth<AV>>
|
|
778
|
+
>,
|
|
779
|
+
) {
|
|
780
|
+
const nsid = 'com.atproto.server.updateEmail' // @ts-ignore
|
|
781
|
+
return this._server.xrpc.method(nsid, cfg)
|
|
782
|
+
}
|
|
735
783
|
}
|
|
736
784
|
|
|
737
785
|
export class SyncNS {
|
package/src/lexicon/lexicons.ts
CHANGED
|
@@ -2242,6 +2242,46 @@ export const schemaDict = {
|
|
|
2242
2242
|
},
|
|
2243
2243
|
},
|
|
2244
2244
|
},
|
|
2245
|
+
ComAtprotoServerConfirmEmail: {
|
|
2246
|
+
lexicon: 1,
|
|
2247
|
+
id: 'com.atproto.server.confirmEmail',
|
|
2248
|
+
defs: {
|
|
2249
|
+
main: {
|
|
2250
|
+
type: 'procedure',
|
|
2251
|
+
description:
|
|
2252
|
+
'Confirm an email using a token from com.atproto.server.requestEmailConfirmation.',
|
|
2253
|
+
input: {
|
|
2254
|
+
encoding: 'application/json',
|
|
2255
|
+
schema: {
|
|
2256
|
+
type: 'object',
|
|
2257
|
+
required: ['email', 'token'],
|
|
2258
|
+
properties: {
|
|
2259
|
+
email: {
|
|
2260
|
+
type: 'string',
|
|
2261
|
+
},
|
|
2262
|
+
token: {
|
|
2263
|
+
type: 'string',
|
|
2264
|
+
},
|
|
2265
|
+
},
|
|
2266
|
+
},
|
|
2267
|
+
},
|
|
2268
|
+
errors: [
|
|
2269
|
+
{
|
|
2270
|
+
name: 'AccountNotFound',
|
|
2271
|
+
},
|
|
2272
|
+
{
|
|
2273
|
+
name: 'ExpiredToken',
|
|
2274
|
+
},
|
|
2275
|
+
{
|
|
2276
|
+
name: 'InvalidToken',
|
|
2277
|
+
},
|
|
2278
|
+
{
|
|
2279
|
+
name: 'InvalidEmail',
|
|
2280
|
+
},
|
|
2281
|
+
],
|
|
2282
|
+
},
|
|
2283
|
+
},
|
|
2284
|
+
},
|
|
2245
2285
|
ComAtprotoServerCreateAccount: {
|
|
2246
2286
|
lexicon: 1,
|
|
2247
2287
|
id: 'com.atproto.server.createAccount',
|
|
@@ -2526,6 +2566,9 @@ export const schemaDict = {
|
|
|
2526
2566
|
email: {
|
|
2527
2567
|
type: 'string',
|
|
2528
2568
|
},
|
|
2569
|
+
emailConfirmed: {
|
|
2570
|
+
type: 'boolean',
|
|
2571
|
+
},
|
|
2529
2572
|
},
|
|
2530
2573
|
},
|
|
2531
2574
|
},
|
|
@@ -2756,6 +2799,9 @@ export const schemaDict = {
|
|
|
2756
2799
|
email: {
|
|
2757
2800
|
type: 'string',
|
|
2758
2801
|
},
|
|
2802
|
+
emailConfirmed: {
|
|
2803
|
+
type: 'boolean',
|
|
2804
|
+
},
|
|
2759
2805
|
},
|
|
2760
2806
|
},
|
|
2761
2807
|
},
|
|
@@ -2854,6 +2900,39 @@ export const schemaDict = {
|
|
|
2854
2900
|
},
|
|
2855
2901
|
},
|
|
2856
2902
|
},
|
|
2903
|
+
ComAtprotoServerRequestEmailConfirmation: {
|
|
2904
|
+
lexicon: 1,
|
|
2905
|
+
id: 'com.atproto.server.requestEmailConfirmation',
|
|
2906
|
+
defs: {
|
|
2907
|
+
main: {
|
|
2908
|
+
type: 'procedure',
|
|
2909
|
+
description:
|
|
2910
|
+
'Request an email with a code to confirm ownership of email',
|
|
2911
|
+
},
|
|
2912
|
+
},
|
|
2913
|
+
},
|
|
2914
|
+
ComAtprotoServerRequestEmailUpdate: {
|
|
2915
|
+
lexicon: 1,
|
|
2916
|
+
id: 'com.atproto.server.requestEmailUpdate',
|
|
2917
|
+
defs: {
|
|
2918
|
+
main: {
|
|
2919
|
+
type: 'procedure',
|
|
2920
|
+
description: 'Request a token in order to update email.',
|
|
2921
|
+
output: {
|
|
2922
|
+
encoding: 'application/json',
|
|
2923
|
+
schema: {
|
|
2924
|
+
type: 'object',
|
|
2925
|
+
required: ['tokenRequired'],
|
|
2926
|
+
properties: {
|
|
2927
|
+
tokenRequired: {
|
|
2928
|
+
type: 'boolean',
|
|
2929
|
+
},
|
|
2930
|
+
},
|
|
2931
|
+
},
|
|
2932
|
+
},
|
|
2933
|
+
},
|
|
2934
|
+
},
|
|
2935
|
+
},
|
|
2857
2936
|
ComAtprotoServerRequestPasswordReset: {
|
|
2858
2937
|
lexicon: 1,
|
|
2859
2938
|
id: 'com.atproto.server.requestPasswordReset',
|
|
@@ -2931,6 +3010,44 @@ export const schemaDict = {
|
|
|
2931
3010
|
},
|
|
2932
3011
|
},
|
|
2933
3012
|
},
|
|
3013
|
+
ComAtprotoServerUpdateEmail: {
|
|
3014
|
+
lexicon: 1,
|
|
3015
|
+
id: 'com.atproto.server.updateEmail',
|
|
3016
|
+
defs: {
|
|
3017
|
+
main: {
|
|
3018
|
+
type: 'procedure',
|
|
3019
|
+
description: "Update an account's email.",
|
|
3020
|
+
input: {
|
|
3021
|
+
encoding: 'application/json',
|
|
3022
|
+
schema: {
|
|
3023
|
+
type: 'object',
|
|
3024
|
+
required: ['email'],
|
|
3025
|
+
properties: {
|
|
3026
|
+
email: {
|
|
3027
|
+
type: 'string',
|
|
3028
|
+
},
|
|
3029
|
+
token: {
|
|
3030
|
+
type: 'string',
|
|
3031
|
+
description:
|
|
3032
|
+
"Requires a token from com.atproto.sever.requestEmailUpdate if the account's email has been confirmed.",
|
|
3033
|
+
},
|
|
3034
|
+
},
|
|
3035
|
+
},
|
|
3036
|
+
},
|
|
3037
|
+
errors: [
|
|
3038
|
+
{
|
|
3039
|
+
name: 'ExpiredToken',
|
|
3040
|
+
},
|
|
3041
|
+
{
|
|
3042
|
+
name: 'InvalidToken',
|
|
3043
|
+
},
|
|
3044
|
+
{
|
|
3045
|
+
name: 'TokenRequired',
|
|
3046
|
+
},
|
|
3047
|
+
],
|
|
3048
|
+
},
|
|
3049
|
+
},
|
|
3050
|
+
},
|
|
2934
3051
|
ComAtprotoSyncGetBlob: {
|
|
2935
3052
|
lexicon: 1,
|
|
2936
3053
|
id: 'com.atproto.sync.getBlob',
|
|
@@ -7240,6 +7357,7 @@ export const ids = {
|
|
|
7240
7357
|
ComAtprotoRepoPutRecord: 'com.atproto.repo.putRecord',
|
|
7241
7358
|
ComAtprotoRepoStrongRef: 'com.atproto.repo.strongRef',
|
|
7242
7359
|
ComAtprotoRepoUploadBlob: 'com.atproto.repo.uploadBlob',
|
|
7360
|
+
ComAtprotoServerConfirmEmail: 'com.atproto.server.confirmEmail',
|
|
7243
7361
|
ComAtprotoServerCreateAccount: 'com.atproto.server.createAccount',
|
|
7244
7362
|
ComAtprotoServerCreateAppPassword: 'com.atproto.server.createAppPassword',
|
|
7245
7363
|
ComAtprotoServerCreateInviteCode: 'com.atproto.server.createInviteCode',
|
|
@@ -7256,10 +7374,14 @@ export const ids = {
|
|
|
7256
7374
|
ComAtprotoServerRefreshSession: 'com.atproto.server.refreshSession',
|
|
7257
7375
|
ComAtprotoServerRequestAccountDelete:
|
|
7258
7376
|
'com.atproto.server.requestAccountDelete',
|
|
7377
|
+
ComAtprotoServerRequestEmailConfirmation:
|
|
7378
|
+
'com.atproto.server.requestEmailConfirmation',
|
|
7379
|
+
ComAtprotoServerRequestEmailUpdate: 'com.atproto.server.requestEmailUpdate',
|
|
7259
7380
|
ComAtprotoServerRequestPasswordReset:
|
|
7260
7381
|
'com.atproto.server.requestPasswordReset',
|
|
7261
7382
|
ComAtprotoServerResetPassword: 'com.atproto.server.resetPassword',
|
|
7262
7383
|
ComAtprotoServerRevokeAppPassword: 'com.atproto.server.revokeAppPassword',
|
|
7384
|
+
ComAtprotoServerUpdateEmail: 'com.atproto.server.updateEmail',
|
|
7263
7385
|
ComAtprotoSyncGetBlob: 'com.atproto.sync.getBlob',
|
|
7264
7386
|
ComAtprotoSyncGetBlocks: 'com.atproto.sync.getBlocks',
|
|
7265
7387
|
ComAtprotoSyncGetCheckout: 'com.atproto.sync.getCheckout',
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GENERATED CODE - DO NOT MODIFY
|
|
3
|
+
*/
|
|
4
|
+
import express from 'express'
|
|
5
|
+
import { ValidationResult, BlobRef } from '@atproto/lexicon'
|
|
6
|
+
import { lexicons } from '../../../../lexicons'
|
|
7
|
+
import { isObj, hasProp } from '../../../../util'
|
|
8
|
+
import { CID } from 'multiformats/cid'
|
|
9
|
+
import { HandlerAuth } from '@atproto/xrpc-server'
|
|
10
|
+
|
|
11
|
+
export interface QueryParams {}
|
|
12
|
+
|
|
13
|
+
export interface InputSchema {
|
|
14
|
+
email: string
|
|
15
|
+
token: string
|
|
16
|
+
[k: string]: unknown
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface HandlerInput {
|
|
20
|
+
encoding: 'application/json'
|
|
21
|
+
body: InputSchema
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface HandlerError {
|
|
25
|
+
status: number
|
|
26
|
+
message?: string
|
|
27
|
+
error?: 'AccountNotFound' | 'ExpiredToken' | 'InvalidToken' | 'InvalidEmail'
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export type HandlerOutput = HandlerError | void
|
|
31
|
+
export 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 type Handler<HA extends HandlerAuth = never> = (
|
|
39
|
+
ctx: HandlerReqCtx<HA>,
|
|
40
|
+
) => Promise<HandlerOutput> | HandlerOutput
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GENERATED CODE - DO NOT MODIFY
|
|
3
|
+
*/
|
|
4
|
+
import express from 'express'
|
|
5
|
+
import { ValidationResult, BlobRef } from '@atproto/lexicon'
|
|
6
|
+
import { lexicons } from '../../../../lexicons'
|
|
7
|
+
import { isObj, hasProp } from '../../../../util'
|
|
8
|
+
import { CID } from 'multiformats/cid'
|
|
9
|
+
import { HandlerAuth } from '@atproto/xrpc-server'
|
|
10
|
+
|
|
11
|
+
export interface QueryParams {}
|
|
12
|
+
|
|
13
|
+
export type InputSchema = undefined
|
|
14
|
+
export type HandlerInput = undefined
|
|
15
|
+
|
|
16
|
+
export interface HandlerError {
|
|
17
|
+
status: number
|
|
18
|
+
message?: string
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export type HandlerOutput = HandlerError | void
|
|
22
|
+
export type HandlerReqCtx<HA extends HandlerAuth = never> = {
|
|
23
|
+
auth: HA
|
|
24
|
+
params: QueryParams
|
|
25
|
+
input: HandlerInput
|
|
26
|
+
req: express.Request
|
|
27
|
+
res: express.Response
|
|
28
|
+
}
|
|
29
|
+
export type Handler<HA extends HandlerAuth = never> = (
|
|
30
|
+
ctx: HandlerReqCtx<HA>,
|
|
31
|
+
) => Promise<HandlerOutput> | HandlerOutput
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GENERATED CODE - DO NOT MODIFY
|
|
3
|
+
*/
|
|
4
|
+
import express from 'express'
|
|
5
|
+
import { ValidationResult, BlobRef } from '@atproto/lexicon'
|
|
6
|
+
import { lexicons } from '../../../../lexicons'
|
|
7
|
+
import { isObj, hasProp } from '../../../../util'
|
|
8
|
+
import { CID } from 'multiformats/cid'
|
|
9
|
+
import { HandlerAuth } from '@atproto/xrpc-server'
|
|
10
|
+
|
|
11
|
+
export interface QueryParams {}
|
|
12
|
+
|
|
13
|
+
export type InputSchema = undefined
|
|
14
|
+
|
|
15
|
+
export interface OutputSchema {
|
|
16
|
+
tokenRequired: boolean
|
|
17
|
+
[k: string]: unknown
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export type HandlerInput = undefined
|
|
21
|
+
|
|
22
|
+
export interface HandlerSuccess {
|
|
23
|
+
encoding: 'application/json'
|
|
24
|
+
body: OutputSchema
|
|
25
|
+
headers?: { [key: string]: string }
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface HandlerError {
|
|
29
|
+
status: number
|
|
30
|
+
message?: string
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export type HandlerOutput = HandlerError | HandlerSuccess
|
|
34
|
+
export type HandlerReqCtx<HA extends HandlerAuth = never> = {
|
|
35
|
+
auth: HA
|
|
36
|
+
params: QueryParams
|
|
37
|
+
input: HandlerInput
|
|
38
|
+
req: express.Request
|
|
39
|
+
res: express.Response
|
|
40
|
+
}
|
|
41
|
+
export type Handler<HA extends HandlerAuth = never> = (
|
|
42
|
+
ctx: HandlerReqCtx<HA>,
|
|
43
|
+
) => Promise<HandlerOutput> | HandlerOutput
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GENERATED CODE - DO NOT MODIFY
|
|
3
|
+
*/
|
|
4
|
+
import express from 'express'
|
|
5
|
+
import { ValidationResult, BlobRef } from '@atproto/lexicon'
|
|
6
|
+
import { lexicons } from '../../../../lexicons'
|
|
7
|
+
import { isObj, hasProp } from '../../../../util'
|
|
8
|
+
import { CID } from 'multiformats/cid'
|
|
9
|
+
import { HandlerAuth } from '@atproto/xrpc-server'
|
|
10
|
+
|
|
11
|
+
export interface QueryParams {}
|
|
12
|
+
|
|
13
|
+
export interface InputSchema {
|
|
14
|
+
email: string
|
|
15
|
+
/** Requires a token from com.atproto.sever.requestEmailUpdate if the account's email has been confirmed. */
|
|
16
|
+
token?: string
|
|
17
|
+
[k: string]: unknown
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface HandlerInput {
|
|
21
|
+
encoding: 'application/json'
|
|
22
|
+
body: InputSchema
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface HandlerError {
|
|
26
|
+
status: number
|
|
27
|
+
message?: string
|
|
28
|
+
error?: 'ExpiredToken' | 'InvalidToken' | 'TokenRequired'
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export type HandlerOutput = HandlerError | void
|
|
32
|
+
export type HandlerReqCtx<HA extends HandlerAuth = never> = {
|
|
33
|
+
auth: HA
|
|
34
|
+
params: QueryParams
|
|
35
|
+
input: HandlerInput
|
|
36
|
+
req: express.Request
|
|
37
|
+
res: express.Response
|
|
38
|
+
}
|
|
39
|
+
export type Handler<HA extends HandlerAuth = never> = (
|
|
40
|
+
ctx: HandlerReqCtx<HA>,
|
|
41
|
+
) => Promise<HandlerOutput> | HandlerOutput
|
|
@@ -83,15 +83,15 @@ export class ActorService {
|
|
|
83
83
|
async getSearchResults({
|
|
84
84
|
cursor,
|
|
85
85
|
limit = 25,
|
|
86
|
-
|
|
86
|
+
query = '',
|
|
87
87
|
includeSoftDeleted,
|
|
88
88
|
}: {
|
|
89
89
|
cursor?: string
|
|
90
90
|
limit?: number
|
|
91
|
-
|
|
91
|
+
query?: string
|
|
92
92
|
includeSoftDeleted?: boolean
|
|
93
93
|
}) {
|
|
94
|
-
const searchField =
|
|
94
|
+
const searchField = query.startsWith('did:') ? 'did' : 'handle'
|
|
95
95
|
let paginatedBuilder
|
|
96
96
|
const { ref } = this.db.db.dynamic
|
|
97
97
|
const paginationOptions = {
|
|
@@ -101,10 +101,10 @@ export class ActorService {
|
|
|
101
101
|
}
|
|
102
102
|
let keyset
|
|
103
103
|
|
|
104
|
-
if (
|
|
104
|
+
if (query && searchField === 'handle') {
|
|
105
105
|
keyset = new SearchKeyset(sql``, sql``)
|
|
106
106
|
paginatedBuilder = getUserSearchQuery(this.db, {
|
|
107
|
-
|
|
107
|
+
query,
|
|
108
108
|
includeSoftDeleted,
|
|
109
109
|
...paginationOptions,
|
|
110
110
|
}).select('distance')
|
|
@@ -114,10 +114,10 @@ export class ActorService {
|
|
|
114
114
|
.select([sql<number>`0`.as('distance')])
|
|
115
115
|
keyset = new ListKeyset(ref('indexedAt'), ref('did'))
|
|
116
116
|
|
|
117
|
-
// When searchField === 'did', the
|
|
118
|
-
// searchField is set to 'did' after checking that the
|
|
119
|
-
if (
|
|
120
|
-
paginatedBuilder = paginatedBuilder.where('actor.did', '=',
|
|
117
|
+
// When searchField === 'did', the query will always be a valid string because
|
|
118
|
+
// searchField is set to 'did' after checking that the query is a valid did
|
|
119
|
+
if (query && searchField === 'did') {
|
|
120
|
+
paginatedBuilder = paginatedBuilder.where('actor.did', '=', query)
|
|
121
121
|
}
|
|
122
122
|
paginatedBuilder = paginate(paginatedBuilder, {
|
|
123
123
|
keyset,
|
|
@@ -7,17 +7,17 @@ import { GenericKeyset, paginate } from '../../db/pagination'
|
|
|
7
7
|
export const getUserSearchQuery = (
|
|
8
8
|
db: Database,
|
|
9
9
|
opts: {
|
|
10
|
-
|
|
10
|
+
query: string
|
|
11
11
|
limit: number
|
|
12
12
|
cursor?: string
|
|
13
13
|
includeSoftDeleted?: boolean
|
|
14
14
|
},
|
|
15
15
|
) => {
|
|
16
16
|
const { ref } = db.db.dynamic
|
|
17
|
-
const {
|
|
17
|
+
const { query, limit, cursor, includeSoftDeleted } = opts
|
|
18
18
|
// Matching user accounts based on handle
|
|
19
|
-
const distanceAccount = distance(
|
|
20
|
-
let accountsQb = getMatchingAccountsQb(db, {
|
|
19
|
+
const distanceAccount = distance(query, ref('handle'))
|
|
20
|
+
let accountsQb = getMatchingAccountsQb(db, { query, includeSoftDeleted })
|
|
21
21
|
accountsQb = paginate(accountsQb, {
|
|
22
22
|
limit,
|
|
23
23
|
cursor,
|
|
@@ -25,8 +25,8 @@ export const getUserSearchQuery = (
|
|
|
25
25
|
keyset: new SearchKeyset(distanceAccount, ref('actor.did')),
|
|
26
26
|
})
|
|
27
27
|
// Matching profiles based on display name
|
|
28
|
-
const distanceProfile = distance(
|
|
29
|
-
let profilesQb = getMatchingProfilesQb(db, {
|
|
28
|
+
const distanceProfile = distance(query, ref('displayName'))
|
|
29
|
+
let profilesQb = getMatchingProfilesQb(db, { query, includeSoftDeleted })
|
|
30
30
|
profilesQb = paginate(profilesQb, {
|
|
31
31
|
limit,
|
|
32
32
|
cursor,
|
|
@@ -46,18 +46,18 @@ export const getUserSearchQuery = (
|
|
|
46
46
|
export const getUserSearchQuerySimple = (
|
|
47
47
|
db: Database,
|
|
48
48
|
opts: {
|
|
49
|
-
|
|
49
|
+
query: string
|
|
50
50
|
limit: number
|
|
51
51
|
},
|
|
52
52
|
) => {
|
|
53
53
|
const { ref } = db.db.dynamic
|
|
54
|
-
const {
|
|
54
|
+
const { query, limit } = opts
|
|
55
55
|
// Matching user accounts based on handle
|
|
56
|
-
const accountsQb = getMatchingAccountsQb(db, {
|
|
56
|
+
const accountsQb = getMatchingAccountsQb(db, { query })
|
|
57
57
|
.orderBy('distance', 'asc')
|
|
58
58
|
.limit(limit)
|
|
59
59
|
// Matching profiles based on display name
|
|
60
|
-
const profilesQb = getMatchingProfilesQb(db, {
|
|
60
|
+
const profilesQb = getMatchingProfilesQb(db, { query })
|
|
61
61
|
.orderBy('distance', 'asc')
|
|
62
62
|
.limit(limit)
|
|
63
63
|
// Combine and paginate result set
|
|
@@ -71,29 +71,29 @@ export const getUserSearchQuerySimple = (
|
|
|
71
71
|
// Matching user accounts based on handle
|
|
72
72
|
const getMatchingAccountsQb = (
|
|
73
73
|
db: Database,
|
|
74
|
-
opts: {
|
|
74
|
+
opts: { query: string; includeSoftDeleted?: boolean },
|
|
75
75
|
) => {
|
|
76
76
|
const { ref } = db.db.dynamic
|
|
77
|
-
const {
|
|
78
|
-
const distanceAccount = distance(
|
|
77
|
+
const { query, includeSoftDeleted } = opts
|
|
78
|
+
const distanceAccount = distance(query, ref('handle'))
|
|
79
79
|
return db.db
|
|
80
80
|
.selectFrom('actor')
|
|
81
81
|
.if(!includeSoftDeleted, (qb) =>
|
|
82
82
|
qb.where(notSoftDeletedClause(ref('actor'))),
|
|
83
83
|
)
|
|
84
84
|
.where('actor.handle', 'is not', null)
|
|
85
|
-
.where(similar(
|
|
85
|
+
.where(similar(query, ref('handle'))) // Coarse filter engaging trigram index
|
|
86
86
|
.select(['actor.did as did', distanceAccount.as('distance')])
|
|
87
87
|
}
|
|
88
88
|
|
|
89
89
|
// Matching profiles based on display name
|
|
90
90
|
const getMatchingProfilesQb = (
|
|
91
91
|
db: Database,
|
|
92
|
-
opts: {
|
|
92
|
+
opts: { query: string; includeSoftDeleted?: boolean },
|
|
93
93
|
) => {
|
|
94
94
|
const { ref } = db.db.dynamic
|
|
95
|
-
const {
|
|
96
|
-
const distanceProfile = distance(
|
|
95
|
+
const { query, includeSoftDeleted } = opts
|
|
96
|
+
const distanceProfile = distance(query, ref('displayName'))
|
|
97
97
|
return db.db
|
|
98
98
|
.selectFrom('profile')
|
|
99
99
|
.innerJoin('actor', 'actor.did', 'profile.creator')
|
|
@@ -101,7 +101,7 @@ const getMatchingProfilesQb = (
|
|
|
101
101
|
qb.where(notSoftDeletedClause(ref('actor'))),
|
|
102
102
|
)
|
|
103
103
|
.where('actor.handle', 'is not', null)
|
|
104
|
-
.where(similar(
|
|
104
|
+
.where(similar(query, ref('displayName'))) // Coarse filter engaging trigram index
|
|
105
105
|
.select(['profile.creator as did', distanceProfile.as('distance')])
|
|
106
106
|
}
|
|
107
107
|
|
|
@@ -133,15 +133,16 @@ const combineAccountsAndProfilesQb = (
|
|
|
133
133
|
}
|
|
134
134
|
|
|
135
135
|
// Remove leading @ in case a handle is input that way
|
|
136
|
-
export const
|
|
136
|
+
export const cleanQuery = (query: string) => query.trim().replace(/^@/g, '')
|
|
137
137
|
|
|
138
|
-
// Uses pg_trgm strict word similarity to check similarity between a search
|
|
139
|
-
const distance = (
|
|
140
|
-
sql<number>`(${
|
|
138
|
+
// Uses pg_trgm strict word similarity to check similarity between a search query and a stored value
|
|
139
|
+
const distance = (query: string, ref: DbRef) =>
|
|
140
|
+
sql<number>`(${query} <<-> ${ref})`
|
|
141
141
|
|
|
142
142
|
// Can utilize trigram index to match on strict word similarity.
|
|
143
143
|
// The word_similarity_threshold is set to .4 (i.e. distance < .6) in db/index.ts.
|
|
144
|
-
const similar = (
|
|
144
|
+
const similar = (query: string, ref: DbRef) =>
|
|
145
|
+
sql<boolean>`(${query} <% ${ref})`
|
|
145
146
|
|
|
146
147
|
type Result = { distance: number; did: string }
|
|
147
148
|
type LabeledResult = { primary: number; secondary: string }
|