@atproto/bsky 0.0.66 → 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.
Files changed (85) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/dist/api/app/bsky/feed/getLikes.d.ts.map +1 -1
  3. package/dist/api/app/bsky/feed/getLikes.js +6 -2
  4. package/dist/api/app/bsky/feed/getLikes.js.map +1 -1
  5. package/dist/api/app/bsky/feed/getRepostedBy.d.ts.map +1 -1
  6. package/dist/api/app/bsky/feed/getRepostedBy.js +6 -2
  7. package/dist/api/app/bsky/feed/getRepostedBy.js.map +1 -1
  8. package/dist/api/app/bsky/graph/getLists.d.ts.map +1 -1
  9. package/dist/api/app/bsky/graph/getLists.js +10 -1
  10. package/dist/api/app/bsky/graph/getLists.js.map +1 -1
  11. package/dist/api/app/bsky/graph/getSuggestedFollowsByActor.d.ts.map +1 -1
  12. package/dist/api/app/bsky/graph/getSuggestedFollowsByActor.js +37 -12
  13. package/dist/api/app/bsky/graph/getSuggestedFollowsByActor.js.map +1 -1
  14. package/dist/api/com/atproto/repo/getRecord.d.ts.map +1 -1
  15. package/dist/api/com/atproto/repo/getRecord.js +27 -19
  16. package/dist/api/com/atproto/repo/getRecord.js.map +1 -1
  17. package/dist/config.d.ts +4 -0
  18. package/dist/config.d.ts.map +1 -1
  19. package/dist/config.js +14 -0
  20. package/dist/config.js.map +1 -1
  21. package/dist/context.d.ts +3 -0
  22. package/dist/context.d.ts.map +1 -1
  23. package/dist/context.js +3 -0
  24. package/dist/context.js.map +1 -1
  25. package/dist/feature-gates.d.ts +25 -0
  26. package/dist/feature-gates.d.ts.map +1 -0
  27. package/dist/feature-gates.js +82 -0
  28. package/dist/feature-gates.js.map +1 -0
  29. package/dist/hydration/hydrator.d.ts +3 -0
  30. package/dist/hydration/hydrator.d.ts.map +1 -1
  31. package/dist/hydration/hydrator.js +67 -44
  32. package/dist/hydration/hydrator.js.map +1 -1
  33. package/dist/hydration/util.d.ts +3 -0
  34. package/dist/hydration/util.d.ts.map +1 -1
  35. package/dist/hydration/util.js +25 -1
  36. package/dist/hydration/util.js.map +1 -1
  37. package/dist/index.d.ts.map +1 -1
  38. package/dist/index.js +8 -0
  39. package/dist/index.js.map +1 -1
  40. package/dist/lexicon/lexicons.d.ts +5 -0
  41. package/dist/lexicon/lexicons.d.ts.map +1 -1
  42. package/dist/lexicon/lexicons.js +7 -0
  43. package/dist/lexicon/lexicons.js.map +1 -1
  44. package/dist/lexicon/types/app/bsky/actor/defs.d.ts +1 -1
  45. package/dist/lexicon/types/app/bsky/actor/defs.d.ts.map +1 -1
  46. package/dist/lexicon/types/app/bsky/actor/defs.js.map +1 -1
  47. package/dist/lexicon/types/app/bsky/embed/record.d.ts +1 -1
  48. package/dist/lexicon/types/app/bsky/embed/record.d.ts.map +1 -1
  49. package/dist/lexicon/types/app/bsky/embed/record.js.map +1 -1
  50. package/dist/lexicon/types/app/bsky/unspecced/getSuggestionsSkeleton.d.ts +2 -0
  51. package/dist/lexicon/types/app/bsky/unspecced/getSuggestionsSkeleton.d.ts.map +1 -1
  52. package/dist/logger.d.ts +1 -0
  53. package/dist/logger.d.ts.map +1 -1
  54. package/dist/logger.js +2 -1
  55. package/dist/logger.js.map +1 -1
  56. package/dist/views/index.d.ts +2 -3
  57. package/dist/views/index.d.ts.map +1 -1
  58. package/dist/views/index.js +21 -13
  59. package/dist/views/index.js.map +1 -1
  60. package/package.json +5 -4
  61. package/src/api/app/bsky/feed/getLikes.ts +6 -2
  62. package/src/api/app/bsky/feed/getRepostedBy.ts +6 -2
  63. package/src/api/app/bsky/graph/getLists.ts +19 -2
  64. package/src/api/app/bsky/graph/getSuggestedFollowsByActor.ts +55 -15
  65. package/src/api/com/atproto/repo/getRecord.ts +28 -19
  66. package/src/config.ts +20 -0
  67. package/src/context.ts +6 -0
  68. package/src/feature-gates.ts +66 -0
  69. package/src/hydration/hydrator.ts +58 -16
  70. package/src/hydration/util.ts +28 -0
  71. package/src/index.ts +9 -0
  72. package/src/lexicon/lexicons.ts +8 -0
  73. package/src/lexicon/types/app/bsky/actor/defs.ts +1 -0
  74. package/src/lexicon/types/app/bsky/embed/record.ts +1 -0
  75. package/src/lexicon/types/app/bsky/unspecced/getSuggestionsSkeleton.ts +2 -0
  76. package/src/logger.ts +2 -0
  77. package/src/views/index.ts +18 -17
  78. package/tests/__snapshots__/feed-generation.test.ts.snap +136 -0
  79. package/tests/feed-generation.test.ts +80 -0
  80. package/tests/hydration/util.test.ts +82 -0
  81. package/tests/seed/known-followers.ts +110 -0
  82. package/tests/views/__snapshots__/lists.test.ts.snap +42 -0
  83. package/tests/views/known-followers.test.ts +160 -0
  84. package/tests/views/lists.test.ts +62 -0
  85. package/tests/views/profile.test.ts +0 -35
@@ -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 },