@atproto/api 0.6.20 → 0.6.22

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 (49) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/LICENSE.txt +7 -0
  3. package/README.md +10 -1
  4. package/definitions/moderation-behaviors.d.ts +1 -0
  5. package/definitions/profile-moderation-behaviors.json +25 -0
  6. package/dist/agent.d.ts +2 -0
  7. package/dist/bsky-agent.d.ts +7 -0
  8. package/dist/client/index.d.ts +12 -0
  9. package/dist/client/lexicons.d.ts +243 -3
  10. package/dist/client/types/app/bsky/actor/defs.d.ts +1 -0
  11. package/dist/client/types/com/atproto/admin/defs.d.ts +28 -0
  12. package/dist/client/types/com/atproto/admin/getAccountInfo.d.ts +16 -0
  13. package/dist/client/types/com/atproto/admin/getSubjectStatus.d.ts +26 -0
  14. package/dist/client/types/com/atproto/admin/searchRepos.d.ts +0 -1
  15. package/dist/client/types/com/atproto/admin/updateSubjectStatus.d.ts +32 -0
  16. package/dist/client/types/com/atproto/server/createAccount.d.ts +4 -2
  17. package/dist/client/types/com/atproto/server/createSession.d.ts +1 -0
  18. package/dist/client/types/com/atproto/server/refreshSession.d.ts +1 -0
  19. package/dist/client/types/com/atproto/server/reserveSigningKey.d.ts +22 -0
  20. package/dist/client/types/com/atproto/sync/listRepos.d.ts +1 -0
  21. package/dist/index.js +878 -425
  22. package/dist/index.js.map +3 -3
  23. package/dist/moderation/accumulator.d.ts +1 -0
  24. package/docs/moderation-behaviors/profiles.md +17 -0
  25. package/package.json +8 -7
  26. package/src/agent.ts +28 -1
  27. package/src/bsky-agent.ts +43 -0
  28. package/src/client/index.ts +52 -0
  29. package/src/client/lexicons.ts +259 -5
  30. package/src/client/types/app/bsky/actor/defs.ts +1 -0
  31. package/src/client/types/com/atproto/admin/defs.ts +61 -0
  32. package/src/client/types/com/atproto/admin/getAccountInfo.ts +32 -0
  33. package/src/client/types/com/atproto/admin/getSubjectStatus.ts +44 -0
  34. package/src/client/types/com/atproto/admin/searchRepos.ts +0 -1
  35. package/src/client/types/com/atproto/admin/updateSubjectStatus.ts +50 -0
  36. package/src/client/types/com/atproto/server/createAccount.ts +4 -2
  37. package/src/client/types/com/atproto/server/createSession.ts +1 -0
  38. package/src/client/types/com/atproto/server/refreshSession.ts +1 -0
  39. package/src/client/types/com/atproto/server/reserveSigningKey.ts +40 -0
  40. package/src/client/types/com/atproto/sync/listRepos.ts +1 -0
  41. package/src/moderation/accumulator.ts +13 -0
  42. package/src/moderation/subjects/account.ts +7 -1
  43. package/tests/agent.test.ts +18 -21
  44. package/tests/bsky-agent.test.ts +19 -25
  45. package/tests/errors.test.ts +5 -11
  46. package/tests/rich-text-detection.test.ts +3 -3
  47. package/tests/util/index.ts +3 -0
  48. package/tests/util/moderation-behavior.ts +10 -2
  49. package/LICENSE +0 -21
@@ -0,0 +1,40 @@
1
+ /**
2
+ * GENERATED CODE - DO NOT MODIFY
3
+ */
4
+ import { Headers, XRPCError } from '@atproto/xrpc'
5
+ import { ValidationResult, BlobRef } from '@atproto/lexicon'
6
+ import { isObj, hasProp } from '../../../../util'
7
+ import { lexicons } from '../../../../lexicons'
8
+ import { CID } from 'multiformats/cid'
9
+
10
+ export interface QueryParams {}
11
+
12
+ export interface InputSchema {
13
+ /** The did to reserve a new did:key for */
14
+ did?: string
15
+ [k: string]: unknown
16
+ }
17
+
18
+ export interface OutputSchema {
19
+ /** Public signing key in the form of a did:key. */
20
+ signingKey: string
21
+ [k: string]: unknown
22
+ }
23
+
24
+ export interface CallOptions {
25
+ headers?: Headers
26
+ qp?: QueryParams
27
+ encoding: 'application/json'
28
+ }
29
+
30
+ export interface Response {
31
+ success: boolean
32
+ headers: Headers
33
+ data: OutputSchema
34
+ }
35
+
36
+ export function toKnownErr(e: any) {
37
+ if (e instanceof XRPCError) {
38
+ }
39
+ return e
40
+ }
@@ -39,6 +39,7 @@ export function toKnownErr(e: any) {
39
39
  export interface Repo {
40
40
  did: string
41
41
  head: string
42
+ rev: string
42
43
  [k: string]: unknown
43
44
  }
44
45
 
@@ -1,4 +1,5 @@
1
1
  import { AppBskyGraphDefs } from '../client/index'
2
+ import { AtUri } from '@atproto/syntax'
2
3
  import {
3
4
  Label,
4
5
  LabelPreference,
@@ -28,6 +29,18 @@ export class ModerationCauseAccumulator {
28
29
  }
29
30
  }
30
31
 
32
+ addBlockingByList(
33
+ blockingByList: AppBskyGraphDefs.ListViewBasic | undefined,
34
+ ) {
35
+ if (blockingByList) {
36
+ this.causes.push({
37
+ type: 'blocking',
38
+ source: { type: 'list', list: blockingByList },
39
+ priority: 3,
40
+ })
41
+ }
42
+ }
43
+
31
44
  addBlockedBy(blockedBy: boolean | undefined) {
32
45
  if (blockedBy) {
33
46
  this.causes.push({
@@ -20,7 +20,13 @@ export function decideAccount(
20
20
  acc.addMuted(subject.viewer?.muted)
21
21
  }
22
22
  }
23
- acc.addBlocking(subject.viewer?.blocking)
23
+ if (subject.viewer?.blocking) {
24
+ if (subject.viewer?.blockingByList) {
25
+ acc.addBlockingByList(subject.viewer?.blockingByList)
26
+ } else {
27
+ acc.addBlocking(subject.viewer?.blocking)
28
+ }
29
+ }
24
30
  acc.addBlockedBy(subject.viewer?.blockedBy)
25
31
 
26
32
  for (const label of filterAccountLabels(subject.labels)) {
@@ -1,29 +1,26 @@
1
1
  import { defaultFetchHandler } from '@atproto/xrpc'
2
- import {
3
- CloseFn,
4
- runTestServer,
5
- TestServerInfo,
6
- } from '@atproto/pds/tests/_util'
7
2
  import {
8
3
  AtpAgent,
9
4
  AtpAgentFetchHandlerResponse,
10
5
  AtpSessionEvent,
11
6
  AtpSessionData,
12
7
  } from '..'
8
+ import { TestNetworkNoAppView } from '@atproto/dev-env'
13
9
 
14
10
  describe('agent', () => {
15
- let server: TestServerInfo
16
- let close: CloseFn
11
+ let network: TestNetworkNoAppView
17
12
 
18
13
  beforeAll(async () => {
19
- server = await runTestServer({
14
+ network = await TestNetworkNoAppView.create({
20
15
  dbPostgresSchema: 'api_agent',
16
+ pds: {
17
+ enableDidDocWithSession: true,
18
+ },
21
19
  })
22
- close = server.close
23
20
  })
24
21
 
25
22
  afterAll(async () => {
26
- await close()
23
+ await network.close()
27
24
  })
28
25
 
29
26
  it('creates a new session on account creation.', async () => {
@@ -34,7 +31,7 @@ describe('agent', () => {
34
31
  sessions.push(sess)
35
32
  }
36
33
 
37
- const agent = new AtpAgent({ service: server.url, persistSession })
34
+ const agent = new AtpAgent({ service: network.pds.url, persistSession })
38
35
 
39
36
  const res = await agent.createAccount({
40
37
  handle: 'user1.test',
@@ -74,7 +71,7 @@ describe('agent', () => {
74
71
  sessions.push(sess)
75
72
  }
76
73
 
77
- const agent1 = new AtpAgent({ service: server.url, persistSession })
74
+ const agent1 = new AtpAgent({ service: network.pds.url, persistSession })
78
75
 
79
76
  const email = 'user2@test.com'
80
77
  await agent1.createAccount({
@@ -83,7 +80,7 @@ describe('agent', () => {
83
80
  password: 'password',
84
81
  })
85
82
 
86
- const agent2 = new AtpAgent({ service: server.url, persistSession })
83
+ const agent2 = new AtpAgent({ service: network.pds.url, persistSession })
87
84
  const res1 = await agent2.login({
88
85
  identifier: 'user2.test',
89
86
  password: 'password',
@@ -122,7 +119,7 @@ describe('agent', () => {
122
119
  sessions.push(sess)
123
120
  }
124
121
 
125
- const agent1 = new AtpAgent({ service: server.url, persistSession })
122
+ const agent1 = new AtpAgent({ service: network.pds.url, persistSession })
126
123
 
127
124
  await agent1.createAccount({
128
125
  handle: 'user3.test',
@@ -133,7 +130,7 @@ describe('agent', () => {
133
130
  throw new Error('No session created')
134
131
  }
135
132
 
136
- const agent2 = new AtpAgent({ service: server.url, persistSession })
133
+ const agent2 = new AtpAgent({ service: network.pds.url, persistSession })
137
134
  const res1 = await agent2.resumeSession(agent1.session)
138
135
 
139
136
  expect(agent2.hasSession).toEqual(true)
@@ -165,7 +162,7 @@ describe('agent', () => {
165
162
  sessions.push(sess)
166
163
  }
167
164
 
168
- const agent = new AtpAgent({ service: server.url, persistSession })
165
+ const agent = new AtpAgent({ service: network.pds.url, persistSession })
169
166
 
170
167
  // create an account and a session with it
171
168
  await agent.createAccount({
@@ -230,7 +227,7 @@ describe('agent', () => {
230
227
  sessions.push(sess)
231
228
  }
232
229
 
233
- const agent = new AtpAgent({ service: server.url, persistSession })
230
+ const agent = new AtpAgent({ service: network.pds.url, persistSession })
234
231
 
235
232
  // create an account and a session with it
236
233
  await agent.createAccount({
@@ -309,7 +306,7 @@ describe('agent', () => {
309
306
  sessions.push(sess)
310
307
  }
311
308
 
312
- const agent = new AtpAgent({ service: server.url, persistSession })
309
+ const agent = new AtpAgent({ service: network.pds.url, persistSession })
313
310
 
314
311
  try {
315
312
  await agent.login({
@@ -349,7 +346,7 @@ describe('agent', () => {
349
346
  sessions.push(sess)
350
347
  }
351
348
 
352
- const agent = new AtpAgent({ service: server.url, persistSession })
349
+ const agent = new AtpAgent({ service: network.pds.url, persistSession })
353
350
 
354
351
  // create an account and a session with it
355
352
  await agent.createAccount({
@@ -420,7 +417,7 @@ describe('agent', () => {
420
417
  newHandlerCallCount++
421
418
  }
422
419
 
423
- const agent = new AtpAgent({ service: server.url, persistSession })
420
+ const agent = new AtpAgent({ service: network.pds.url, persistSession })
424
421
 
425
422
  await agent.createAccount({
426
423
  handle: 'user7.test',
@@ -452,7 +449,7 @@ describe('agent', () => {
452
449
  sessions.push(sess)
453
450
  }
454
451
 
455
- const agent = new AtpAgent({ service: server.url, persistSession })
452
+ const agent = new AtpAgent({ service: network.pds.url, persistSession })
456
453
 
457
454
  await expect(
458
455
  agent.createAccount({
@@ -1,23 +1,17 @@
1
- import {
2
- CloseFn,
3
- runTestServer,
4
- TestServerInfo,
5
- } from '@atproto/pds/tests/_util'
1
+ import { TestNetworkNoAppView } from '@atproto/dev-env'
6
2
  import { BskyAgent, ComAtprotoRepoPutRecord, AppBskyActorProfile } from '..'
7
3
 
8
4
  describe('agent', () => {
9
- let server: TestServerInfo
10
- let close: CloseFn
5
+ let network: TestNetworkNoAppView
11
6
 
12
7
  beforeAll(async () => {
13
- server = await runTestServer({
8
+ network = await TestNetworkNoAppView.create({
14
9
  dbPostgresSchema: 'bsky_agent',
15
10
  })
16
- close = server.close
17
11
  })
18
12
 
19
13
  afterAll(async () => {
20
- await close()
14
+ await network.close()
21
15
  })
22
16
 
23
17
  const getProfileDisplayName = async (
@@ -35,7 +29,7 @@ describe('agent', () => {
35
29
  }
36
30
 
37
31
  it('upsertProfile correctly creates and updates profiles.', async () => {
38
- const agent = new BskyAgent({ service: server.url })
32
+ const agent = new BskyAgent({ service: network.pds.url })
39
33
 
40
34
  await agent.createAccount({
41
35
  handle: 'user1.test',
@@ -67,7 +61,7 @@ describe('agent', () => {
67
61
  })
68
62
 
69
63
  it('upsertProfile correctly handles CAS failures.', async () => {
70
- const agent = new BskyAgent({ service: server.url })
64
+ const agent = new BskyAgent({ service: network.pds.url })
71
65
 
72
66
  await agent.createAccount({
73
67
  handle: 'user2.test',
@@ -106,7 +100,7 @@ describe('agent', () => {
106
100
  })
107
101
 
108
102
  it('upsertProfile wont endlessly retry CAS failures.', async () => {
109
- const agent = new BskyAgent({ service: server.url })
103
+ const agent = new BskyAgent({ service: network.pds.url })
110
104
 
111
105
  await agent.createAccount({
112
106
  handle: 'user3.test',
@@ -135,7 +129,7 @@ describe('agent', () => {
135
129
  })
136
130
 
137
131
  it('upsertProfile validates the record.', async () => {
138
- const agent = new BskyAgent({ service: server.url })
132
+ const agent = new BskyAgent({ service: network.pds.url })
139
133
 
140
134
  await agent.createAccount({
141
135
  handle: 'user4.test',
@@ -153,70 +147,70 @@ describe('agent', () => {
153
147
 
154
148
  describe('app', () => {
155
149
  it('should retrieve the api app', () => {
156
- const agent = new BskyAgent({ service: server.url })
150
+ const agent = new BskyAgent({ service: network.pds.url })
157
151
  expect(agent.app).toBe(agent.api.app)
158
152
  })
159
153
  })
160
154
 
161
155
  describe('post', () => {
162
156
  it('should throw if no session', async () => {
163
- const agent = new BskyAgent({ service: server.url })
157
+ const agent = new BskyAgent({ service: network.pds.url })
164
158
  await expect(agent.post({ text: 'foo' })).rejects.toThrow('Not logged in')
165
159
  })
166
160
  })
167
161
 
168
162
  describe('deletePost', () => {
169
163
  it('should throw if no session', async () => {
170
- const agent = new BskyAgent({ service: server.url })
164
+ const agent = new BskyAgent({ service: network.pds.url })
171
165
  await expect(agent.deletePost('foo')).rejects.toThrow('Not logged in')
172
166
  })
173
167
  })
174
168
 
175
169
  describe('like', () => {
176
170
  it('should throw if no session', async () => {
177
- const agent = new BskyAgent({ service: server.url })
171
+ const agent = new BskyAgent({ service: network.pds.url })
178
172
  await expect(agent.like('foo', 'bar')).rejects.toThrow('Not logged in')
179
173
  })
180
174
  })
181
175
 
182
176
  describe('deleteLike', () => {
183
177
  it('should throw if no session', async () => {
184
- const agent = new BskyAgent({ service: server.url })
178
+ const agent = new BskyAgent({ service: network.pds.url })
185
179
  await expect(agent.deleteLike('foo')).rejects.toThrow('Not logged in')
186
180
  })
187
181
  })
188
182
 
189
183
  describe('repost', () => {
190
184
  it('should throw if no session', async () => {
191
- const agent = new BskyAgent({ service: server.url })
185
+ const agent = new BskyAgent({ service: network.pds.url })
192
186
  await expect(agent.repost('foo', 'bar')).rejects.toThrow('Not logged in')
193
187
  })
194
188
  })
195
189
 
196
190
  describe('deleteRepost', () => {
197
191
  it('should throw if no session', async () => {
198
- const agent = new BskyAgent({ service: server.url })
192
+ const agent = new BskyAgent({ service: network.pds.url })
199
193
  await expect(agent.deleteRepost('foo')).rejects.toThrow('Not logged in')
200
194
  })
201
195
  })
202
196
 
203
197
  describe('follow', () => {
204
198
  it('should throw if no session', async () => {
205
- const agent = new BskyAgent({ service: server.url })
199
+ const agent = new BskyAgent({ service: network.pds.url })
206
200
  await expect(agent.follow('foo')).rejects.toThrow('Not logged in')
207
201
  })
208
202
  })
209
203
 
210
204
  describe('deleteFollow', () => {
211
205
  it('should throw if no session', async () => {
212
- const agent = new BskyAgent({ service: server.url })
206
+ const agent = new BskyAgent({ service: network.pds.url })
213
207
  await expect(agent.deleteFollow('foo')).rejects.toThrow('Not logged in')
214
208
  })
215
209
  })
216
210
 
217
211
  describe('preferences methods', () => {
218
212
  it('gets and sets preferences correctly', async () => {
219
- const agent = new BskyAgent({ service: server.url })
213
+ const agent = new BskyAgent({ service: network.pds.url })
220
214
 
221
215
  await agent.createAccount({
222
216
  handle: 'user5.test',
@@ -714,7 +708,7 @@ describe('agent', () => {
714
708
  })
715
709
 
716
710
  it('resolves duplicates correctly', async () => {
717
- const agent = new BskyAgent({ service: server.url })
711
+ const agent = new BskyAgent({ service: network.pds.url })
718
712
 
719
713
  await agent.createAccount({
720
714
  handle: 'user6.test',
@@ -1,25 +1,19 @@
1
- import {
2
- CloseFn,
3
- runTestServer,
4
- TestServerInfo,
5
- } from '@atproto/pds/tests/_util'
6
1
  import { AtpAgent, ComAtprotoServerCreateAccount } from '..'
2
+ import { TestNetworkNoAppView } from '@atproto/dev-env'
7
3
 
8
4
  describe('errors', () => {
9
- let server: TestServerInfo
5
+ let network: TestNetworkNoAppView
10
6
  let client: AtpAgent
11
- let close: CloseFn
12
7
 
13
8
  beforeAll(async () => {
14
- server = await runTestServer({
9
+ network = await TestNetworkNoAppView.create({
15
10
  dbPostgresSchema: 'known_errors',
16
11
  })
17
- client = new AtpAgent({ service: server.url })
18
- close = server.close
12
+ client = network.pds.getClient()
19
13
  })
20
14
 
21
15
  afterAll(async () => {
22
- await close()
16
+ await network.close()
23
17
  })
24
18
 
25
19
  it('constructs the correct error instance', async () => {
@@ -295,10 +295,10 @@ describe('detectFacets', () => {
295
295
  const rt = new RichText({ text: input })
296
296
  await rt.detectFacets(agent)
297
297
 
298
- let detectedTags: string[] = []
299
- let detectedIndices: { byteStart: number; byteEnd: number }[] = []
298
+ const detectedTags: string[] = []
299
+ const detectedIndices: { byteStart: number; byteEnd: number }[] = []
300
300
 
301
- for (const { facet, ...rest } of rt.segments()) {
301
+ for (const { facet } of rt.segments()) {
302
302
  if (!facet) continue
303
303
  for (const feature of facet.features) {
304
304
  if (isTag(feature)) {
@@ -135,6 +135,7 @@ export const mock = {
135
135
  mutedByList,
136
136
  blockedBy,
137
137
  blocking,
138
+ blockingByList,
138
139
  following,
139
140
  followedBy,
140
141
  }: {
@@ -142,6 +143,7 @@ export const mock = {
142
143
  mutedByList?: AppBskyGraphDefs.ListViewBasic
143
144
  blockedBy?: boolean
144
145
  blocking?: string
146
+ blockingByList?: AppBskyGraphDefs.ListViewBasic
145
147
  following?: string
146
148
  followedBy?: string
147
149
  }): AppBskyActorDefs.ViewerState {
@@ -150,6 +152,7 @@ export const mock = {
150
152
  mutedByList,
151
153
  blockedBy,
152
154
  blocking,
155
+ blockingByList,
153
156
  following,
154
157
  followedBy,
155
158
  }
@@ -25,6 +25,10 @@ expect.extend({
25
25
  if (actual.cause.source.type === 'list') {
26
26
  cause = 'muted-by-list'
27
27
  }
28
+ } else if (actual.cause?.type === 'blocking') {
29
+ if (actual.cause.source.type === 'list') {
30
+ cause = 'blocking-by-list'
31
+ }
28
32
  }
29
33
  if (!expected) {
30
34
  if (!ignoreCause && actual.cause) {
@@ -153,8 +157,12 @@ export class ModerationBehaviorSuiteRunner {
153
157
  ? m.listViewBasic({ name: 'Fake List' })
154
158
  : undefined,
155
159
  blockedBy: def.blockedBy,
156
- blocking: def.blocking
157
- ? 'at://did:web:self.test/app.bsky.graph.block/fake'
160
+ blocking:
161
+ def.blocking || def.blockingByList
162
+ ? 'at://did:web:self.test/app.bsky.graph.block/fake'
163
+ : undefined,
164
+ blockingByList: def.blockingByList
165
+ ? m.listViewBasic({ name: 'Fake List' })
158
166
  : undefined,
159
167
  }),
160
168
  })
package/LICENSE DELETED
@@ -1,21 +0,0 @@
1
- MIT License
2
-
3
- Copyright (c) 2022-2023 Bluesky PBC
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.