@atproto/bsky 0.0.65 → 0.0.67
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 +16 -0
- package/dist/api/app/bsky/actor/getSuggestions.js +1 -1
- package/dist/api/app/bsky/actor/getSuggestions.js.map +1 -1
- package/dist/api/app/bsky/feed/getLikes.d.ts.map +1 -1
- package/dist/api/app/bsky/feed/getLikes.js +6 -2
- package/dist/api/app/bsky/feed/getLikes.js.map +1 -1
- package/dist/api/app/bsky/feed/getRepostedBy.d.ts.map +1 -1
- package/dist/api/app/bsky/feed/getRepostedBy.js +6 -2
- package/dist/api/app/bsky/feed/getRepostedBy.js.map +1 -1
- package/dist/api/app/bsky/graph/getLists.d.ts.map +1 -1
- package/dist/api/app/bsky/graph/getLists.js +10 -1
- package/dist/api/app/bsky/graph/getLists.js.map +1 -1
- package/dist/api/app/bsky/graph/getSuggestedFollowsByActor.d.ts.map +1 -1
- package/dist/api/app/bsky/graph/getSuggestedFollowsByActor.js +37 -12
- package/dist/api/app/bsky/graph/getSuggestedFollowsByActor.js.map +1 -1
- package/dist/api/com/atproto/repo/getRecord.d.ts.map +1 -1
- package/dist/api/com/atproto/repo/getRecord.js +27 -19
- package/dist/api/com/atproto/repo/getRecord.js.map +1 -1
- package/dist/config.d.ts +4 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +14 -0
- package/dist/config.js.map +1 -1
- package/dist/context.d.ts +3 -0
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +3 -0
- package/dist/context.js.map +1 -1
- package/dist/feature-gates.d.ts +25 -0
- package/dist/feature-gates.d.ts.map +1 -0
- package/dist/feature-gates.js +82 -0
- package/dist/feature-gates.js.map +1 -0
- package/dist/hydration/hydrator.d.ts +3 -0
- package/dist/hydration/hydrator.d.ts.map +1 -1
- package/dist/hydration/hydrator.js +67 -44
- package/dist/hydration/hydrator.js.map +1 -1
- package/dist/hydration/util.d.ts +3 -0
- package/dist/hydration/util.d.ts.map +1 -1
- package/dist/hydration/util.js +25 -1
- package/dist/hydration/util.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -1
- package/dist/lexicon/lexicons.d.ts +35 -0
- package/dist/lexicon/lexicons.d.ts.map +1 -1
- package/dist/lexicon/lexicons.js +39 -1
- package/dist/lexicon/lexicons.js.map +1 -1
- package/dist/lexicon/types/app/bsky/actor/defs.d.ts +17 -1
- package/dist/lexicon/types/app/bsky/actor/defs.d.ts.map +1 -1
- package/dist/lexicon/types/app/bsky/actor/defs.js +21 -1
- package/dist/lexicon/types/app/bsky/actor/defs.js.map +1 -1
- package/dist/lexicon/types/app/bsky/embed/record.d.ts +1 -1
- package/dist/lexicon/types/app/bsky/embed/record.d.ts.map +1 -1
- package/dist/lexicon/types/app/bsky/embed/record.js.map +1 -1
- package/dist/lexicon/types/app/bsky/unspecced/getSuggestionsSkeleton.d.ts +2 -0
- package/dist/lexicon/types/app/bsky/unspecced/getSuggestionsSkeleton.d.ts.map +1 -1
- package/dist/logger.d.ts +1 -0
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +2 -1
- package/dist/logger.js.map +1 -1
- package/dist/views/index.d.ts +3 -3
- package/dist/views/index.d.ts.map +1 -1
- package/dist/views/index.js +41 -8
- package/dist/views/index.js.map +1 -1
- package/package.json +5 -4
- package/src/api/app/bsky/actor/getSuggestions.ts +1 -1
- package/src/api/app/bsky/feed/getLikes.ts +6 -2
- package/src/api/app/bsky/feed/getRepostedBy.ts +6 -2
- package/src/api/app/bsky/graph/getLists.ts +19 -2
- package/src/api/app/bsky/graph/getSuggestedFollowsByActor.ts +55 -15
- package/src/api/com/atproto/repo/getRecord.ts +28 -19
- package/src/config.ts +20 -0
- package/src/context.ts +6 -0
- package/src/feature-gates.ts +66 -0
- package/src/hydration/hydrator.ts +58 -16
- package/src/hydration/util.ts +28 -0
- package/src/index.ts +9 -0
- package/src/lexicon/lexicons.ts +43 -1
- package/src/lexicon/types/app/bsky/actor/defs.ts +40 -0
- package/src/lexicon/types/app/bsky/embed/record.ts +1 -0
- package/src/lexicon/types/app/bsky/unspecced/getSuggestionsSkeleton.ts +2 -0
- package/src/logger.ts +2 -0
- package/src/views/index.ts +40 -12
- package/tests/__snapshots__/feed-generation.test.ts.snap +136 -0
- package/tests/feed-generation.test.ts +80 -0
- package/tests/hydration/util.test.ts +82 -0
- package/tests/seed/known-followers.ts +110 -0
- package/tests/views/__snapshots__/lists.test.ts.snap +42 -0
- package/tests/views/known-followers.test.ts +160 -0
- package/tests/views/lists.test.ts +62 -0
- package/tests/views/profile.test.ts +0 -35
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`bsky actor likes feed views does not include reference lists in getActorLists 1`] = `
|
|
4
|
+
Array [
|
|
5
|
+
Object {
|
|
6
|
+
"cid": "cids(0)",
|
|
7
|
+
"creator": Object {
|
|
8
|
+
"avatar": "https://bsky.public.url/img/avatar/plain/user(1)/cids(1)@jpeg",
|
|
9
|
+
"createdAt": "1970-01-01T00:00:00.000Z",
|
|
10
|
+
"description": "its me!",
|
|
11
|
+
"did": "user(0)",
|
|
12
|
+
"displayName": "ali",
|
|
13
|
+
"handle": "alice.test",
|
|
14
|
+
"indexedAt": "1970-01-01T00:00:00.000Z",
|
|
15
|
+
"labels": Array [
|
|
16
|
+
Object {
|
|
17
|
+
"cid": "cids(2)",
|
|
18
|
+
"cts": "1970-01-01T00:00:00.000Z",
|
|
19
|
+
"src": "user(0)",
|
|
20
|
+
"uri": "record(1)",
|
|
21
|
+
"val": "self-label-a",
|
|
22
|
+
},
|
|
23
|
+
Object {
|
|
24
|
+
"cid": "cids(2)",
|
|
25
|
+
"cts": "1970-01-01T00:00:00.000Z",
|
|
26
|
+
"src": "user(0)",
|
|
27
|
+
"uri": "record(1)",
|
|
28
|
+
"val": "self-label-b",
|
|
29
|
+
},
|
|
30
|
+
],
|
|
31
|
+
},
|
|
32
|
+
"description": "",
|
|
33
|
+
"descriptionFacets": Array [],
|
|
34
|
+
"indexedAt": "1970-01-01T00:00:00.000Z",
|
|
35
|
+
"labels": Array [],
|
|
36
|
+
"listItemCount": 0,
|
|
37
|
+
"name": "cool curate list!",
|
|
38
|
+
"purpose": "app.bsky.graph.defs#curatelist",
|
|
39
|
+
"uri": "record(0)",
|
|
40
|
+
},
|
|
41
|
+
]
|
|
42
|
+
`;
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { TestNetwork, SeedClient } from '@atproto/dev-env'
|
|
2
|
+
import AtpAgent from '@atproto/api'
|
|
3
|
+
|
|
4
|
+
import { knownFollowersSeed } from '../seed/known-followers'
|
|
5
|
+
|
|
6
|
+
describe('known followers (social proof)', () => {
|
|
7
|
+
let network: TestNetwork
|
|
8
|
+
let agent: AtpAgent
|
|
9
|
+
let pdsAgent: AtpAgent
|
|
10
|
+
let seedClient: SeedClient
|
|
11
|
+
|
|
12
|
+
let dids: Record<string, string>
|
|
13
|
+
|
|
14
|
+
beforeAll(async () => {
|
|
15
|
+
network = await TestNetwork.create({
|
|
16
|
+
dbPostgresSchema: 'bsky_views_block',
|
|
17
|
+
})
|
|
18
|
+
agent = network.bsky.getClient()
|
|
19
|
+
pdsAgent = network.pds.getClient()
|
|
20
|
+
seedClient = network.getSeedClient()
|
|
21
|
+
|
|
22
|
+
await knownFollowersSeed(seedClient)
|
|
23
|
+
|
|
24
|
+
dids = seedClient.dids
|
|
25
|
+
|
|
26
|
+
/*
|
|
27
|
+
* First-party block
|
|
28
|
+
*/
|
|
29
|
+
await pdsAgent.api.app.bsky.graph.block.create(
|
|
30
|
+
{ repo: dids.fp_block_view },
|
|
31
|
+
{ createdAt: new Date().toISOString(), subject: dids.fp_block_res_1 },
|
|
32
|
+
seedClient.getHeaders(dids.fp_block_view),
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
/*
|
|
36
|
+
* Second-party block
|
|
37
|
+
*/
|
|
38
|
+
await pdsAgent.api.app.bsky.graph.block.create(
|
|
39
|
+
{ repo: dids.sp_block_sub },
|
|
40
|
+
{ createdAt: new Date().toISOString(), subject: dids.sp_block_res_1 },
|
|
41
|
+
seedClient.getHeaders(dids.sp_block_sub),
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
/*
|
|
45
|
+
* Mix of blocks and non
|
|
46
|
+
*/
|
|
47
|
+
await pdsAgent.api.app.bsky.graph.block.create(
|
|
48
|
+
{ repo: dids.mix_view },
|
|
49
|
+
{ createdAt: new Date().toISOString(), subject: dids.mix_fp_block_res },
|
|
50
|
+
seedClient.getHeaders(dids.mix_view),
|
|
51
|
+
)
|
|
52
|
+
await pdsAgent.api.app.bsky.graph.block.create(
|
|
53
|
+
{ repo: dids.mix_sub_1 },
|
|
54
|
+
{ createdAt: new Date().toISOString(), subject: dids.mix_sp_block_res },
|
|
55
|
+
seedClient.getHeaders(dids.mix_sub_1),
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
await network.processAll()
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
afterAll(async () => {
|
|
62
|
+
await network.close()
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
/*
|
|
66
|
+
* Note that this test arbitrarily uses `getFollows` bc atm it returns
|
|
67
|
+
* `ProfileViewBasic`. This method could be updated one day to return
|
|
68
|
+
* `knownFollowers`, in which case this test would begin failing.
|
|
69
|
+
*/
|
|
70
|
+
it('basic profile views do not return knownFollowers', async () => {
|
|
71
|
+
const { data } = await agent.api.app.bsky.graph.getFollows(
|
|
72
|
+
{ actor: dids.base_res_1 },
|
|
73
|
+
{ headers: await network.serviceHeaders(dids.base_view) },
|
|
74
|
+
)
|
|
75
|
+
const follow = data.follows[0]
|
|
76
|
+
|
|
77
|
+
expect(follow.viewer?.knownFollowers).toBeFalsy()
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
it('getKnownFollowers: returns data', async () => {
|
|
81
|
+
const { data } = await agent.api.app.bsky.graph.getKnownFollowers(
|
|
82
|
+
{ actor: dids.base_sub },
|
|
83
|
+
{ headers: await network.serviceHeaders(dids.base_view) },
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
expect(data.subject.did).toBe(dids.base_sub)
|
|
87
|
+
expect(data.followers.length).toBe(1)
|
|
88
|
+
expect(data.followers[0].did).toBe(dids.base_res_1)
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
it('getProfile: returns knownFollowers', async () => {
|
|
92
|
+
const { data } = await agent.api.app.bsky.actor.getProfile(
|
|
93
|
+
{ actor: dids.base_sub },
|
|
94
|
+
{ headers: await network.serviceHeaders(dids.base_view) },
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
const knownFollowers = data.viewer?.knownFollowers
|
|
98
|
+
expect(knownFollowers?.count).toBe(1)
|
|
99
|
+
expect(knownFollowers?.followers).toHaveLength(1)
|
|
100
|
+
expect(knownFollowers?.followers[0].did).toBe(dids.base_res_1)
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
it('getProfile: filters 1st-party blocks', async () => {
|
|
104
|
+
const { data } = await agent.api.app.bsky.actor.getProfile(
|
|
105
|
+
{ actor: dids.fp_block_sub },
|
|
106
|
+
{ headers: await network.serviceHeaders(dids.fp_block_view) },
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
const knownFollowers = data.viewer?.knownFollowers
|
|
110
|
+
expect(knownFollowers?.count).toBe(1)
|
|
111
|
+
expect(knownFollowers?.followers).toHaveLength(0)
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
it('getProfile: filters second-party blocks', async () => {
|
|
115
|
+
const result = await agent.api.app.bsky.actor.getProfile(
|
|
116
|
+
{ actor: dids.sp_block_sub },
|
|
117
|
+
{ headers: await network.serviceHeaders(dids.sp_block_view) },
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
const knownFollowers = result.data.viewer?.knownFollowers
|
|
121
|
+
expect(knownFollowers?.count).toBe(1)
|
|
122
|
+
expect(knownFollowers?.followers).toHaveLength(0)
|
|
123
|
+
})
|
|
124
|
+
|
|
125
|
+
it('getProfiles: filters second-party blocks', async () => {
|
|
126
|
+
const result = await agent.api.app.bsky.actor.getProfiles(
|
|
127
|
+
{ actors: [dids.sp_block_sub] },
|
|
128
|
+
{ headers: await network.serviceHeaders(dids.sp_block_view) },
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
expect(result.data.profiles).toHaveLength(1)
|
|
132
|
+
const profile = result.data.profiles[0]
|
|
133
|
+
const knownFollowers = profile.viewer?.knownFollowers
|
|
134
|
+
expect(knownFollowers?.count).toBe(1)
|
|
135
|
+
expect(knownFollowers?.followers).toHaveLength(0)
|
|
136
|
+
})
|
|
137
|
+
|
|
138
|
+
it('getProfiles: mix of results', async () => {
|
|
139
|
+
const result = await agent.api.app.bsky.actor.getProfiles(
|
|
140
|
+
{ actors: [dids.mix_sub_1, dids.mix_sub_2, dids.mix_sub_3] },
|
|
141
|
+
{ headers: await network.serviceHeaders(dids.mix_view) },
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
expect(result.data.profiles).toHaveLength(3)
|
|
145
|
+
|
|
146
|
+
const [sub_1, sub_2, sub_3] = result.data.profiles
|
|
147
|
+
|
|
148
|
+
const sub_1_kf = sub_1.viewer?.knownFollowers
|
|
149
|
+
expect(sub_1_kf?.count).toBe(3)
|
|
150
|
+
expect(sub_1_kf?.followers).toHaveLength(1)
|
|
151
|
+
|
|
152
|
+
const sub_2_kf = sub_2.viewer?.knownFollowers
|
|
153
|
+
expect(sub_2_kf?.count).toBe(3)
|
|
154
|
+
expect(sub_2_kf?.followers).toHaveLength(2)
|
|
155
|
+
|
|
156
|
+
const sub_3_kf = sub_3.viewer?.knownFollowers
|
|
157
|
+
expect(sub_3_kf?.count).toBe(3)
|
|
158
|
+
expect(sub_3_kf?.followers).toHaveLength(2)
|
|
159
|
+
})
|
|
160
|
+
})
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import AtpAgent from '@atproto/api'
|
|
2
|
+
import { TestNetwork, SeedClient, basicSeed } from '@atproto/dev-env'
|
|
3
|
+
import { forSnapshot } from '../_util'
|
|
4
|
+
|
|
5
|
+
describe('bsky actor likes feed views', () => {
|
|
6
|
+
let network: TestNetwork
|
|
7
|
+
let agent: AtpAgent
|
|
8
|
+
let pdsAgent: AtpAgent
|
|
9
|
+
let sc: SeedClient
|
|
10
|
+
|
|
11
|
+
beforeAll(async () => {
|
|
12
|
+
network = await TestNetwork.create({
|
|
13
|
+
dbPostgresSchema: 'bsky_views_actor_lists',
|
|
14
|
+
})
|
|
15
|
+
agent = network.bsky.getClient()
|
|
16
|
+
pdsAgent = network.pds.getClient()
|
|
17
|
+
sc = network.getSeedClient()
|
|
18
|
+
await basicSeed(sc)
|
|
19
|
+
await network.processAll()
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
afterAll(async () => {
|
|
23
|
+
await network.close()
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
it('does not include reference lists in getActorLists', async () => {
|
|
27
|
+
await pdsAgent.api.app.bsky.graph.list.create(
|
|
28
|
+
{
|
|
29
|
+
repo: sc.dids.alice,
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
name: 'awesome starter pack list!',
|
|
33
|
+
description: '',
|
|
34
|
+
descriptionFacets: [],
|
|
35
|
+
avatar: undefined,
|
|
36
|
+
createdAt: new Date().toISOString(),
|
|
37
|
+
purpose: 'app.bsky.graph.defs#referencelist',
|
|
38
|
+
},
|
|
39
|
+
sc.getHeaders(sc.dids.alice),
|
|
40
|
+
)
|
|
41
|
+
await pdsAgent.api.app.bsky.graph.list.create(
|
|
42
|
+
{
|
|
43
|
+
repo: sc.dids.alice,
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
name: 'cool curate list!',
|
|
47
|
+
description: '',
|
|
48
|
+
descriptionFacets: [],
|
|
49
|
+
avatar: undefined,
|
|
50
|
+
createdAt: new Date().toISOString(),
|
|
51
|
+
purpose: 'app.bsky.graph.defs#curatelist',
|
|
52
|
+
},
|
|
53
|
+
sc.getHeaders(sc.dids.alice),
|
|
54
|
+
)
|
|
55
|
+
await network.processAll()
|
|
56
|
+
const view = await agent.api.app.bsky.graph.getLists({
|
|
57
|
+
actor: sc.dids.alice,
|
|
58
|
+
})
|
|
59
|
+
expect(view.data.lists.length).toBe(1)
|
|
60
|
+
expect(forSnapshot(view.data.lists)).toMatchSnapshot()
|
|
61
|
+
})
|
|
62
|
+
})
|
|
@@ -14,7 +14,6 @@ describe('pds profile views', () => {
|
|
|
14
14
|
let alice: string
|
|
15
15
|
let bob: string
|
|
16
16
|
let dan: string
|
|
17
|
-
let carol: string
|
|
18
17
|
|
|
19
18
|
beforeAll(async () => {
|
|
20
19
|
network = await TestNetwork.create({
|
|
@@ -28,7 +27,6 @@ describe('pds profile views', () => {
|
|
|
28
27
|
alice = sc.dids.alice
|
|
29
28
|
bob = sc.dids.bob
|
|
30
29
|
dan = sc.dids.dan
|
|
31
|
-
carol = sc.dids.carol
|
|
32
30
|
})
|
|
33
31
|
|
|
34
32
|
afterAll(async () => {
|
|
@@ -78,39 +76,6 @@ describe('pds profile views', () => {
|
|
|
78
76
|
expect(forSnapshot(danForBob.data)).toMatchSnapshot()
|
|
79
77
|
})
|
|
80
78
|
|
|
81
|
-
it('returns knownFollowers viewer data', async () => {
|
|
82
|
-
const carolForAlice = await agent.api.app.bsky.actor.getProfile(
|
|
83
|
-
{ actor: carol },
|
|
84
|
-
{ headers: await network.serviceHeaders(alice) },
|
|
85
|
-
)
|
|
86
|
-
|
|
87
|
-
const knownFollowers = carolForAlice.data.viewer?.knownFollowers
|
|
88
|
-
expect(knownFollowers?.count).toBe(1)
|
|
89
|
-
expect(knownFollowers?.followers).toHaveLength(1)
|
|
90
|
-
expect(knownFollowers?.followers[0].handle).toBe('bob.test')
|
|
91
|
-
})
|
|
92
|
-
|
|
93
|
-
it('does not return knownFollowers for basic profile views', async () => {
|
|
94
|
-
const { data } = await agent.api.app.bsky.graph.getFollows(
|
|
95
|
-
{ actor: carol },
|
|
96
|
-
{ headers: await network.serviceHeaders(alice) },
|
|
97
|
-
)
|
|
98
|
-
const follow = data.follows[0]
|
|
99
|
-
|
|
100
|
-
expect(follow.viewer?.knownFollowers).toBeFalsy()
|
|
101
|
-
})
|
|
102
|
-
|
|
103
|
-
it('getKnownFollowers works', async () => {
|
|
104
|
-
const { data } = await agent.api.app.bsky.graph.getKnownFollowers(
|
|
105
|
-
{ actor: carol },
|
|
106
|
-
{ headers: await network.serviceHeaders(alice) },
|
|
107
|
-
)
|
|
108
|
-
|
|
109
|
-
expect(data.subject.did).toBe(carol)
|
|
110
|
-
expect(data.followers.length).toBe(1)
|
|
111
|
-
expect(data.followers[0].handle).toBe('bob.test')
|
|
112
|
-
})
|
|
113
|
-
|
|
114
79
|
it('fetches multiple profiles', async () => {
|
|
115
80
|
const {
|
|
116
81
|
data: { profiles },
|