@atproto/bsky 0.0.214 → 0.0.216
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 +17 -0
- package/dist/api/app/bsky/graph/getSuggestedFollowsByActor.js +2 -0
- package/dist/api/app/bsky/graph/getSuggestedFollowsByActor.js.map +1 -1
- package/dist/api/app/bsky/unspecced/getSuggestedOnboardingUsers.d.ts +4 -0
- package/dist/api/app/bsky/unspecced/getSuggestedOnboardingUsers.d.ts.map +1 -0
- package/dist/api/app/bsky/unspecced/getSuggestedOnboardingUsers.js +104 -0
- package/dist/api/app/bsky/unspecced/getSuggestedOnboardingUsers.js.map +1 -0
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +2 -0
- package/dist/api/index.js.map +1 -1
- package/dist/feature-gates.d.ts +1 -0
- package/dist/feature-gates.d.ts.map +1 -1
- package/dist/feature-gates.js +1 -0
- package/dist/feature-gates.js.map +1 -1
- package/dist/lexicon/index.d.ts +4 -0
- package/dist/lexicon/index.d.ts.map +1 -1
- package/dist/lexicon/index.js +8 -0
- package/dist/lexicon/index.js.map +1 -1
- package/dist/lexicon/lexicons.d.ts +244 -10
- package/dist/lexicon/lexicons.d.ts.map +1 -1
- package/dist/lexicon/lexicons.js +124 -5
- package/dist/lexicon/lexicons.js.map +1 -1
- package/dist/lexicon/types/app/bsky/draft/defs.d.ts +1 -1
- package/dist/lexicon/types/app/bsky/draft/defs.d.ts.map +1 -1
- package/dist/lexicon/types/app/bsky/draft/defs.js.map +1 -1
- package/dist/lexicon/types/app/bsky/graph/getSuggestedFollowsByActor.d.ts +3 -1
- package/dist/lexicon/types/app/bsky/graph/getSuggestedFollowsByActor.d.ts.map +1 -1
- package/dist/lexicon/types/app/bsky/graph/getSuggestedFollowsByActor.js.map +1 -1
- package/dist/lexicon/types/app/bsky/unspecced/getOnboardingSuggestedUsersSkeleton.d.ts +27 -0
- package/dist/lexicon/types/app/bsky/unspecced/getOnboardingSuggestedUsersSkeleton.d.ts.map +1 -0
- package/dist/lexicon/types/app/bsky/unspecced/getOnboardingSuggestedUsersSkeleton.js +7 -0
- package/dist/lexicon/types/app/bsky/unspecced/getOnboardingSuggestedUsersSkeleton.js.map +1 -0
- package/dist/lexicon/types/app/bsky/unspecced/getSuggestedOnboardingUsers.d.ts +26 -0
- package/dist/lexicon/types/app/bsky/unspecced/getSuggestedOnboardingUsers.d.ts.map +1 -0
- package/dist/lexicon/types/app/bsky/unspecced/getSuggestedOnboardingUsers.js +7 -0
- package/dist/lexicon/types/app/bsky/unspecced/getSuggestedOnboardingUsers.js.map +1 -0
- package/dist/lexicon/types/app/bsky/unspecced/getSuggestionsSkeleton.d.ts +3 -1
- package/dist/lexicon/types/app/bsky/unspecced/getSuggestionsSkeleton.d.ts.map +1 -1
- package/dist/lexicon/types/app/bsky/unspecced/getSuggestionsSkeleton.js.map +1 -1
- package/dist/lexicon/types/com/germnetwork/declaration.d.ts +7 -1
- package/dist/lexicon/types/com/germnetwork/declaration.d.ts.map +1 -1
- package/dist/lexicon/types/com/germnetwork/declaration.js.map +1 -1
- package/package.json +8 -8
- package/src/api/app/bsky/graph/getSuggestedFollowsByActor.ts +3 -0
- package/src/api/app/bsky/unspecced/getSuggestedOnboardingUsers.ts +176 -0
- package/src/api/index.ts +2 -0
- package/src/feature-gates.ts +1 -0
- package/src/lexicon/index.ts +26 -0
- package/src/lexicon/lexicons.ts +136 -5
- package/src/lexicon/types/app/bsky/draft/defs.ts +1 -1
- package/src/lexicon/types/app/bsky/graph/getSuggestedFollowsByActor.ts +3 -1
- package/src/lexicon/types/app/bsky/unspecced/getOnboardingSuggestedUsersSkeleton.ts +45 -0
- package/src/lexicon/types/app/bsky/unspecced/getSuggestedOnboardingUsers.ts +44 -0
- package/src/lexicon/types/app/bsky/unspecced/getSuggestionsSkeleton.ts +3 -1
- package/src/lexicon/types/com/germnetwork/declaration.ts +7 -1
- package/tests/views/get-suggested-onboarding-users.test.ts +186 -0
- package/tsconfig.build.tsbuildinfo +1 -1
package/src/lexicon/lexicons.ts
CHANGED
|
@@ -2392,9 +2392,10 @@ export const schemaDict = {
|
|
|
2392
2392
|
properties: {
|
|
2393
2393
|
text: {
|
|
2394
2394
|
type: 'string',
|
|
2395
|
-
maxLength:
|
|
2396
|
-
maxGraphemes:
|
|
2397
|
-
description:
|
|
2395
|
+
maxLength: 10000,
|
|
2396
|
+
maxGraphemes: 1000,
|
|
2397
|
+
description:
|
|
2398
|
+
'The primary post content. It has a higher limit than post contents to allow storing a larger text that can later be refined into smaller posts.',
|
|
2398
2399
|
},
|
|
2399
2400
|
labels: {
|
|
2400
2401
|
type: 'union',
|
|
@@ -6242,6 +6243,10 @@ export const schemaDict = {
|
|
|
6242
6243
|
},
|
|
6243
6244
|
recId: {
|
|
6244
6245
|
type: 'integer',
|
|
6246
|
+
description: 'DEPRECATED: use recIdStr instead.',
|
|
6247
|
+
},
|
|
6248
|
+
recIdStr: {
|
|
6249
|
+
type: 'string',
|
|
6245
6250
|
description:
|
|
6246
6251
|
'Snowflake for this recommendation, use when submitting recommendation events.',
|
|
6247
6252
|
},
|
|
@@ -8055,6 +8060,59 @@ export const schemaDict = {
|
|
|
8055
8060
|
},
|
|
8056
8061
|
},
|
|
8057
8062
|
},
|
|
8063
|
+
AppBskyUnspeccedGetOnboardingSuggestedUsersSkeleton: {
|
|
8064
|
+
lexicon: 1,
|
|
8065
|
+
id: 'app.bsky.unspecced.getOnboardingSuggestedUsersSkeleton',
|
|
8066
|
+
defs: {
|
|
8067
|
+
main: {
|
|
8068
|
+
type: 'query',
|
|
8069
|
+
description:
|
|
8070
|
+
'Get a skeleton of suggested users for onboarding. Intended to be called and hydrated by app.bsky.unspecced.getSuggestedOnboardingUsers',
|
|
8071
|
+
parameters: {
|
|
8072
|
+
type: 'params',
|
|
8073
|
+
properties: {
|
|
8074
|
+
viewer: {
|
|
8075
|
+
type: 'string',
|
|
8076
|
+
format: 'did',
|
|
8077
|
+
description:
|
|
8078
|
+
'DID of the account making the request (not included for public/unauthenticated queries).',
|
|
8079
|
+
},
|
|
8080
|
+
category: {
|
|
8081
|
+
type: 'string',
|
|
8082
|
+
description: 'Category of users to get suggestions for.',
|
|
8083
|
+
},
|
|
8084
|
+
limit: {
|
|
8085
|
+
type: 'integer',
|
|
8086
|
+
minimum: 1,
|
|
8087
|
+
maximum: 50,
|
|
8088
|
+
default: 25,
|
|
8089
|
+
},
|
|
8090
|
+
},
|
|
8091
|
+
},
|
|
8092
|
+
output: {
|
|
8093
|
+
encoding: 'application/json',
|
|
8094
|
+
schema: {
|
|
8095
|
+
type: 'object',
|
|
8096
|
+
required: ['dids'],
|
|
8097
|
+
properties: {
|
|
8098
|
+
dids: {
|
|
8099
|
+
type: 'array',
|
|
8100
|
+
items: {
|
|
8101
|
+
type: 'string',
|
|
8102
|
+
format: 'did',
|
|
8103
|
+
},
|
|
8104
|
+
},
|
|
8105
|
+
recId: {
|
|
8106
|
+
type: 'string',
|
|
8107
|
+
description:
|
|
8108
|
+
'Snowflake for this recommendation, use when submitting recommendation events.',
|
|
8109
|
+
},
|
|
8110
|
+
},
|
|
8111
|
+
},
|
|
8112
|
+
},
|
|
8113
|
+
},
|
|
8114
|
+
},
|
|
8115
|
+
},
|
|
8058
8116
|
AppBskyUnspeccedGetPopularFeedGenerators: {
|
|
8059
8117
|
lexicon: 1,
|
|
8060
8118
|
id: 'app.bsky.unspecced.getPopularFeedGenerators',
|
|
@@ -8343,6 +8401,52 @@ export const schemaDict = {
|
|
|
8343
8401
|
},
|
|
8344
8402
|
},
|
|
8345
8403
|
},
|
|
8404
|
+
AppBskyUnspeccedGetSuggestedOnboardingUsers: {
|
|
8405
|
+
lexicon: 1,
|
|
8406
|
+
id: 'app.bsky.unspecced.getSuggestedOnboardingUsers',
|
|
8407
|
+
defs: {
|
|
8408
|
+
main: {
|
|
8409
|
+
type: 'query',
|
|
8410
|
+
description: 'Get a list of suggested users for onboarding',
|
|
8411
|
+
parameters: {
|
|
8412
|
+
type: 'params',
|
|
8413
|
+
properties: {
|
|
8414
|
+
category: {
|
|
8415
|
+
type: 'string',
|
|
8416
|
+
description: 'Category of users to get suggestions for.',
|
|
8417
|
+
},
|
|
8418
|
+
limit: {
|
|
8419
|
+
type: 'integer',
|
|
8420
|
+
minimum: 1,
|
|
8421
|
+
maximum: 50,
|
|
8422
|
+
default: 25,
|
|
8423
|
+
},
|
|
8424
|
+
},
|
|
8425
|
+
},
|
|
8426
|
+
output: {
|
|
8427
|
+
encoding: 'application/json',
|
|
8428
|
+
schema: {
|
|
8429
|
+
type: 'object',
|
|
8430
|
+
required: ['actors'],
|
|
8431
|
+
properties: {
|
|
8432
|
+
actors: {
|
|
8433
|
+
type: 'array',
|
|
8434
|
+
items: {
|
|
8435
|
+
type: 'ref',
|
|
8436
|
+
ref: 'lex:app.bsky.actor.defs#profileView',
|
|
8437
|
+
},
|
|
8438
|
+
},
|
|
8439
|
+
recId: {
|
|
8440
|
+
type: 'string',
|
|
8441
|
+
description:
|
|
8442
|
+
'Snowflake for this recommendation, use when submitting recommendation events.',
|
|
8443
|
+
},
|
|
8444
|
+
},
|
|
8445
|
+
},
|
|
8446
|
+
},
|
|
8447
|
+
},
|
|
8448
|
+
},
|
|
8449
|
+
},
|
|
8346
8450
|
AppBskyUnspeccedGetSuggestedStarterPacks: {
|
|
8347
8451
|
lexicon: 1,
|
|
8348
8452
|
id: 'app.bsky.unspecced.getSuggestedStarterPacks',
|
|
@@ -8581,6 +8685,10 @@ export const schemaDict = {
|
|
|
8581
8685
|
},
|
|
8582
8686
|
recId: {
|
|
8583
8687
|
type: 'integer',
|
|
8688
|
+
description: 'DEPRECATED: use recIdStr instead.',
|
|
8689
|
+
},
|
|
8690
|
+
recIdStr: {
|
|
8691
|
+
type: 'string',
|
|
8584
8692
|
description:
|
|
8585
8693
|
'Snowflake for this recommendation, use when submitting recommendation events.',
|
|
8586
8694
|
},
|
|
@@ -15346,7 +15454,7 @@ export const schemaDict = {
|
|
|
15346
15454
|
defs: {
|
|
15347
15455
|
main: {
|
|
15348
15456
|
type: 'record',
|
|
15349
|
-
description: 'A
|
|
15457
|
+
description: 'A declaration of a Germ Network account',
|
|
15350
15458
|
key: 'literal:self',
|
|
15351
15459
|
record: {
|
|
15352
15460
|
type: 'object',
|
|
@@ -15354,22 +15462,33 @@ export const schemaDict = {
|
|
|
15354
15462
|
properties: {
|
|
15355
15463
|
version: {
|
|
15356
15464
|
type: 'string',
|
|
15465
|
+
description:
|
|
15466
|
+
'Semver version number, without pre-release or build information, for the format of opaque content',
|
|
15467
|
+
minLength: 5,
|
|
15468
|
+
maxLength: 14,
|
|
15357
15469
|
},
|
|
15358
15470
|
currentKey: {
|
|
15359
15471
|
type: 'bytes',
|
|
15472
|
+
description:
|
|
15473
|
+
'Opaque value, an ed25519 public key prefixed with a byte enum',
|
|
15360
15474
|
},
|
|
15361
15475
|
messageMe: {
|
|
15362
15476
|
type: 'ref',
|
|
15477
|
+
description: 'Controls who can message this account',
|
|
15363
15478
|
ref: 'lex:com.germnetwork.declaration#messageMe',
|
|
15364
15479
|
},
|
|
15365
15480
|
keyPackage: {
|
|
15366
15481
|
type: 'bytes',
|
|
15482
|
+
description:
|
|
15483
|
+
'Opaque value, contains MLS KeyPackage(s), and other signature data, and is signed by the currentKey',
|
|
15367
15484
|
},
|
|
15368
15485
|
continuityProofs: {
|
|
15369
15486
|
type: 'array',
|
|
15487
|
+
description: 'Array of opaque values to allow for key rolling',
|
|
15370
15488
|
items: {
|
|
15371
15489
|
type: 'bytes',
|
|
15372
15490
|
},
|
|
15491
|
+
maxLength: 1000,
|
|
15373
15492
|
},
|
|
15374
15493
|
},
|
|
15375
15494
|
},
|
|
@@ -15380,11 +15499,19 @@ export const schemaDict = {
|
|
|
15380
15499
|
properties: {
|
|
15381
15500
|
messageMeUrl: {
|
|
15382
15501
|
type: 'string',
|
|
15502
|
+
description:
|
|
15503
|
+
'A URL to present to an account that does not have its own com.germnetwork.declaration record, must have an empty fragment component, where the app should fill in the fragment component with the DIDs of the two accounts who wish to message each other',
|
|
15383
15504
|
format: 'uri',
|
|
15505
|
+
minLength: 1,
|
|
15506
|
+
maxLength: 2047,
|
|
15384
15507
|
},
|
|
15385
15508
|
showButtonTo: {
|
|
15386
15509
|
type: 'string',
|
|
15387
|
-
knownValues: ['usersIFollow', 'everyone'],
|
|
15510
|
+
knownValues: ['none', 'usersIFollow', 'everyone'],
|
|
15511
|
+
description:
|
|
15512
|
+
"The policy of who can message the account, this value is included in the keyPackage, but is duplicated here to allow applications to decide if they should show a 'Message on Germ' button to the viewer.",
|
|
15513
|
+
minLength: 1,
|
|
15514
|
+
maxLength: 100,
|
|
15388
15515
|
},
|
|
15389
15516
|
},
|
|
15390
15517
|
},
|
|
@@ -15547,6 +15674,8 @@ export const ids = {
|
|
|
15547
15674
|
'app.bsky.unspecced.getOnboardingSuggestedStarterPacks',
|
|
15548
15675
|
AppBskyUnspeccedGetOnboardingSuggestedStarterPacksSkeleton:
|
|
15549
15676
|
'app.bsky.unspecced.getOnboardingSuggestedStarterPacksSkeleton',
|
|
15677
|
+
AppBskyUnspeccedGetOnboardingSuggestedUsersSkeleton:
|
|
15678
|
+
'app.bsky.unspecced.getOnboardingSuggestedUsersSkeleton',
|
|
15550
15679
|
AppBskyUnspeccedGetPopularFeedGenerators:
|
|
15551
15680
|
'app.bsky.unspecced.getPopularFeedGenerators',
|
|
15552
15681
|
AppBskyUnspeccedGetPostThreadOtherV2:
|
|
@@ -15555,6 +15684,8 @@ export const ids = {
|
|
|
15555
15684
|
AppBskyUnspeccedGetSuggestedFeeds: 'app.bsky.unspecced.getSuggestedFeeds',
|
|
15556
15685
|
AppBskyUnspeccedGetSuggestedFeedsSkeleton:
|
|
15557
15686
|
'app.bsky.unspecced.getSuggestedFeedsSkeleton',
|
|
15687
|
+
AppBskyUnspeccedGetSuggestedOnboardingUsers:
|
|
15688
|
+
'app.bsky.unspecced.getSuggestedOnboardingUsers',
|
|
15558
15689
|
AppBskyUnspeccedGetSuggestedStarterPacks:
|
|
15559
15690
|
'app.bsky.unspecced.getSuggestedStarterPacks',
|
|
15560
15691
|
AppBskyUnspeccedGetSuggestedStarterPacksSkeleton:
|
|
@@ -75,7 +75,7 @@ export function validateDraft<V>(v: V) {
|
|
|
75
75
|
/** One of the posts that compose a draft. */
|
|
76
76
|
export interface DraftPost {
|
|
77
77
|
$type?: 'app.bsky.draft.defs#draftPost'
|
|
78
|
-
/** The primary post content. */
|
|
78
|
+
/** The primary post content. It has a higher limit than post contents to allow storing a larger text that can later be refined into smaller posts. */
|
|
79
79
|
text: string
|
|
80
80
|
labels?: $Typed<ComAtprotoLabelDefs.SelfLabels> | { $type: string }
|
|
81
81
|
embedImages?: DraftEmbedImage[]
|
|
@@ -24,8 +24,10 @@ export interface OutputSchema {
|
|
|
24
24
|
suggestions: AppBskyActorDefs.ProfileView[]
|
|
25
25
|
/** If true, response has fallen-back to generic results, and is not scoped using relativeToDid */
|
|
26
26
|
isFallback?: boolean
|
|
27
|
-
/**
|
|
27
|
+
/** DEPRECATED: use recIdStr instead. */
|
|
28
28
|
recId?: number
|
|
29
|
+
/** Snowflake for this recommendation, use when submitting recommendation events. */
|
|
30
|
+
recIdStr?: string
|
|
29
31
|
}
|
|
30
32
|
|
|
31
33
|
export type HandlerInput = void
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GENERATED CODE - DO NOT MODIFY
|
|
3
|
+
*/
|
|
4
|
+
import { type ValidationResult, BlobRef } from '@atproto/lexicon'
|
|
5
|
+
import { CID } from 'multiformats/cid'
|
|
6
|
+
import { validate as _validate } from '../../../../lexicons'
|
|
7
|
+
import {
|
|
8
|
+
type $Typed,
|
|
9
|
+
is$typed as _is$typed,
|
|
10
|
+
type OmitKey,
|
|
11
|
+
} from '../../../../util'
|
|
12
|
+
|
|
13
|
+
const is$typed = _is$typed,
|
|
14
|
+
validate = _validate
|
|
15
|
+
const id = 'app.bsky.unspecced.getOnboardingSuggestedUsersSkeleton'
|
|
16
|
+
|
|
17
|
+
export type QueryParams = {
|
|
18
|
+
/** DID of the account making the request (not included for public/unauthenticated queries). */
|
|
19
|
+
viewer?: string
|
|
20
|
+
/** Category of users to get suggestions for. */
|
|
21
|
+
category?: string
|
|
22
|
+
limit: number
|
|
23
|
+
}
|
|
24
|
+
export type InputSchema = undefined
|
|
25
|
+
|
|
26
|
+
export interface OutputSchema {
|
|
27
|
+
dids: string[]
|
|
28
|
+
/** Snowflake for this recommendation, use when submitting recommendation events. */
|
|
29
|
+
recId?: string
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export type HandlerInput = void
|
|
33
|
+
|
|
34
|
+
export interface HandlerSuccess {
|
|
35
|
+
encoding: 'application/json'
|
|
36
|
+
body: OutputSchema
|
|
37
|
+
headers?: { [key: string]: string }
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface HandlerError {
|
|
41
|
+
status: number
|
|
42
|
+
message?: string
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export type HandlerOutput = HandlerError | HandlerSuccess
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GENERATED CODE - DO NOT MODIFY
|
|
3
|
+
*/
|
|
4
|
+
import { type ValidationResult, BlobRef } from '@atproto/lexicon'
|
|
5
|
+
import { CID } from 'multiformats/cid'
|
|
6
|
+
import { validate as _validate } from '../../../../lexicons'
|
|
7
|
+
import {
|
|
8
|
+
type $Typed,
|
|
9
|
+
is$typed as _is$typed,
|
|
10
|
+
type OmitKey,
|
|
11
|
+
} from '../../../../util'
|
|
12
|
+
import type * as AppBskyActorDefs from '../actor/defs.js'
|
|
13
|
+
|
|
14
|
+
const is$typed = _is$typed,
|
|
15
|
+
validate = _validate
|
|
16
|
+
const id = 'app.bsky.unspecced.getSuggestedOnboardingUsers'
|
|
17
|
+
|
|
18
|
+
export type QueryParams = {
|
|
19
|
+
/** Category of users to get suggestions for. */
|
|
20
|
+
category?: string
|
|
21
|
+
limit: number
|
|
22
|
+
}
|
|
23
|
+
export type InputSchema = undefined
|
|
24
|
+
|
|
25
|
+
export interface OutputSchema {
|
|
26
|
+
actors: AppBskyActorDefs.ProfileView[]
|
|
27
|
+
/** Snowflake for this recommendation, use when submitting recommendation events. */
|
|
28
|
+
recId?: string
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export type HandlerInput = void
|
|
32
|
+
|
|
33
|
+
export interface HandlerSuccess {
|
|
34
|
+
encoding: 'application/json'
|
|
35
|
+
body: OutputSchema
|
|
36
|
+
headers?: { [key: string]: string }
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface HandlerError {
|
|
40
|
+
status: number
|
|
41
|
+
message?: string
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export type HandlerOutput = HandlerError | HandlerSuccess
|
|
@@ -30,8 +30,10 @@ export interface OutputSchema {
|
|
|
30
30
|
actors: AppBskyUnspeccedDefs.SkeletonSearchActor[]
|
|
31
31
|
/** DID of the account these suggestions are relative to. If this is returned undefined, suggestions are based on the viewer. */
|
|
32
32
|
relativeToDid?: string
|
|
33
|
-
/**
|
|
33
|
+
/** DEPRECATED: use recIdStr instead. */
|
|
34
34
|
recId?: number
|
|
35
|
+
/** Snowflake for this recommendation, use when submitting recommendation events. */
|
|
36
|
+
recIdStr?: string
|
|
35
37
|
}
|
|
36
38
|
|
|
37
39
|
export type HandlerInput = void
|
|
@@ -12,10 +12,14 @@ const id = 'com.germnetwork.declaration'
|
|
|
12
12
|
|
|
13
13
|
export interface Main {
|
|
14
14
|
$type: 'com.germnetwork.declaration'
|
|
15
|
+
/** Semver version number, without pre-release or build information, for the format of opaque content */
|
|
15
16
|
version: string
|
|
17
|
+
/** Opaque value, an ed25519 public key prefixed with a byte enum */
|
|
16
18
|
currentKey: Uint8Array
|
|
17
19
|
messageMe?: MessageMe
|
|
20
|
+
/** Opaque value, contains MLS KeyPackage(s), and other signature data, and is signed by the currentKey */
|
|
18
21
|
keyPackage?: Uint8Array
|
|
22
|
+
/** Array of opaque values to allow for key rolling */
|
|
19
23
|
continuityProofs?: Uint8Array[]
|
|
20
24
|
[k: string]: unknown
|
|
21
25
|
}
|
|
@@ -38,8 +42,10 @@ export {
|
|
|
38
42
|
|
|
39
43
|
export interface MessageMe {
|
|
40
44
|
$type?: 'com.germnetwork.declaration#messageMe'
|
|
45
|
+
/** A URL to present to an account that does not have its own com.germnetwork.declaration record, must have an empty fragment component, where the app should fill in the fragment component with the DIDs of the two accounts who wish to message each other */
|
|
41
46
|
messageMeUrl: string
|
|
42
|
-
|
|
47
|
+
/** The policy of who can message the account, this value is included in the keyPackage, but is duplicated here to allow applications to decide if they should show a 'Message on Germ' button to the viewer. */
|
|
48
|
+
showButtonTo: 'none' | 'usersIFollow' | 'everyone' | (string & {})
|
|
43
49
|
}
|
|
44
50
|
|
|
45
51
|
const hashMessageMe = 'messageMe'
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { once } from 'node:events'
|
|
2
|
+
import { Server, createServer } from 'node:http'
|
|
3
|
+
import { AddressInfo } from 'node:net'
|
|
4
|
+
import express, { Application } from 'express'
|
|
5
|
+
import AtpAgent from '@atproto/api'
|
|
6
|
+
import { SeedClient, TestNetwork } from '@atproto/dev-env'
|
|
7
|
+
import { ids } from '../../src/lexicon/lexicons'
|
|
8
|
+
import { OutputSchema } from '../../src/lexicon/types/app/bsky/unspecced/getSuggestedUsersSkeleton'
|
|
9
|
+
|
|
10
|
+
type User = {
|
|
11
|
+
id: string
|
|
12
|
+
did: string
|
|
13
|
+
email: string
|
|
14
|
+
handle: string
|
|
15
|
+
password: string
|
|
16
|
+
displayName: string
|
|
17
|
+
description: string
|
|
18
|
+
selfLabels: undefined
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function createUser(name: string): User {
|
|
22
|
+
return {
|
|
23
|
+
id: name,
|
|
24
|
+
// @ts-ignore overwritten below
|
|
25
|
+
did: undefined,
|
|
26
|
+
email: `${name}@test.com`,
|
|
27
|
+
handle: `${name}.test`,
|
|
28
|
+
password: `${name}-pass`,
|
|
29
|
+
displayName: name,
|
|
30
|
+
description: `hi im ${name}`,
|
|
31
|
+
selfLabels: undefined,
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const users = {
|
|
36
|
+
suggestedUser: createUser('suggested-user'),
|
|
37
|
+
viewer: createUser('viewer'),
|
|
38
|
+
viewerBlocker: createUser('viewer-blocker'),
|
|
39
|
+
followedUser: createUser('followed-user'),
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
type Users = typeof users
|
|
43
|
+
|
|
44
|
+
async function seed(sc: SeedClient) {
|
|
45
|
+
const u = structuredClone(users)
|
|
46
|
+
|
|
47
|
+
for (const [key, user] of Object.entries(u)) {
|
|
48
|
+
await sc.createAccount(key, user)
|
|
49
|
+
u[key].did = sc.dids[key]
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
await sc.block(u.viewerBlocker.did, u.suggestedUser.did)
|
|
53
|
+
await sc.follow(u.viewer.did, u.followedUser.did)
|
|
54
|
+
|
|
55
|
+
await sc.network.processAll()
|
|
56
|
+
|
|
57
|
+
return { users: u }
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
describe('getSuggestedOnboardingUsers', () => {
|
|
61
|
+
let network: TestNetwork
|
|
62
|
+
let agent: AtpAgent
|
|
63
|
+
let sc: SeedClient
|
|
64
|
+
let seededUsers: Users
|
|
65
|
+
let mockServer: MockServer
|
|
66
|
+
|
|
67
|
+
beforeAll(async () => {
|
|
68
|
+
mockServer = new MockServer()
|
|
69
|
+
await mockServer.listen()
|
|
70
|
+
|
|
71
|
+
network = await TestNetwork.create({
|
|
72
|
+
dbPostgresSchema: 'bsky_tests_get_suggested_onboarding_users',
|
|
73
|
+
bsky: {
|
|
74
|
+
topicsUrl: mockServer.url,
|
|
75
|
+
topicsApiKey: 'test',
|
|
76
|
+
},
|
|
77
|
+
})
|
|
78
|
+
agent = network.bsky.getClient()
|
|
79
|
+
sc = network.getSeedClient()
|
|
80
|
+
|
|
81
|
+
const result = await seed(sc)
|
|
82
|
+
seededUsers = result.users
|
|
83
|
+
|
|
84
|
+
await network.processAll()
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
afterAll(async () => {
|
|
88
|
+
await network.close()
|
|
89
|
+
await mockServer.stop()
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
describe(`basic handling`, () => {
|
|
93
|
+
beforeAll(() => {
|
|
94
|
+
mockServer.mockedDids.set('suggestedUser', seededUsers.suggestedUser.did)
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
afterAll(() => {
|
|
98
|
+
mockServer.mockedDids.delete('suggestedUser')
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
it(`returns users for non-blocking viewer`, async () => {
|
|
102
|
+
const { data } =
|
|
103
|
+
await agent.app.bsky.unspecced.getSuggestedOnboardingUsers(undefined, {
|
|
104
|
+
headers: await network.serviceHeaders(
|
|
105
|
+
seededUsers.viewer.did,
|
|
106
|
+
ids.AppBskyUnspeccedGetSuggestedOnboardingUsers,
|
|
107
|
+
),
|
|
108
|
+
})
|
|
109
|
+
const actor = data.actors.find(
|
|
110
|
+
(a) => a.did === seededUsers.suggestedUser.did,
|
|
111
|
+
)
|
|
112
|
+
expect(actor).toBeDefined()
|
|
113
|
+
})
|
|
114
|
+
|
|
115
|
+
it(`does not return user if blocked by viewer`, async () => {
|
|
116
|
+
const { data } =
|
|
117
|
+
await agent.app.bsky.unspecced.getSuggestedOnboardingUsers(undefined, {
|
|
118
|
+
headers: await network.serviceHeaders(
|
|
119
|
+
seededUsers.viewerBlocker.did,
|
|
120
|
+
ids.AppBskyUnspeccedGetSuggestedOnboardingUsers,
|
|
121
|
+
),
|
|
122
|
+
})
|
|
123
|
+
const actor = data.actors.find(
|
|
124
|
+
(a) => a.did === seededUsers.suggestedUser.did,
|
|
125
|
+
)
|
|
126
|
+
expect(actor).not.toBeDefined()
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
it(`does not return users that viewer already follows`, async () => {
|
|
130
|
+
mockServer.mockedDids.set('followedUser', seededUsers.followedUser.did)
|
|
131
|
+
const { data } =
|
|
132
|
+
await agent.app.bsky.unspecced.getSuggestedOnboardingUsers(undefined, {
|
|
133
|
+
headers: await network.serviceHeaders(
|
|
134
|
+
seededUsers.viewer.did,
|
|
135
|
+
ids.AppBskyUnspeccedGetSuggestedOnboardingUsers,
|
|
136
|
+
),
|
|
137
|
+
})
|
|
138
|
+
const actor = data.actors.find(
|
|
139
|
+
(a) => a.did === seededUsers.followedUser.did,
|
|
140
|
+
)
|
|
141
|
+
expect(actor).not.toBeDefined()
|
|
142
|
+
mockServer.mockedDids.delete('followedUser')
|
|
143
|
+
})
|
|
144
|
+
})
|
|
145
|
+
})
|
|
146
|
+
|
|
147
|
+
class MockServer {
|
|
148
|
+
app: Application
|
|
149
|
+
server: Server
|
|
150
|
+
|
|
151
|
+
mockedDids = new Map<string, string>()
|
|
152
|
+
|
|
153
|
+
constructor() {
|
|
154
|
+
this.app = this.createApp()
|
|
155
|
+
this.server = createServer(this.app)
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
async listen(port?: number) {
|
|
159
|
+
this.server.listen(port)
|
|
160
|
+
await once(this.server, 'listening')
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
async stop() {
|
|
164
|
+
this.server.close()
|
|
165
|
+
await once(this.server, 'close')
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
get url() {
|
|
169
|
+
const address = this.server.address() as AddressInfo
|
|
170
|
+
return `http://localhost:${address.port}`
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
private createApp() {
|
|
174
|
+
const app = express()
|
|
175
|
+
app.get(
|
|
176
|
+
'/xrpc/app.bsky.unspecced.getSuggestedUsersSkeleton',
|
|
177
|
+
(req, res) => {
|
|
178
|
+
const skeleton: OutputSchema = {
|
|
179
|
+
dids: Array.from(this.mockedDids.values()),
|
|
180
|
+
}
|
|
181
|
+
return res.json(skeleton)
|
|
182
|
+
},
|
|
183
|
+
)
|
|
184
|
+
return app
|
|
185
|
+
}
|
|
186
|
+
}
|