@atproto/api 0.3.3 → 0.3.5

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 (28) hide show
  1. package/bench/agent.bench.ts +9 -0
  2. package/dist/client/lexicons.d.ts +38 -0
  3. package/dist/client/types/app/bsky/feed/describeFeedGenerator.d.ts +33 -0
  4. package/dist/client/types/app/bsky/feed/generator.d.ts +1 -1
  5. package/dist/client/types/app/bsky/feed/getFeed.d.ts +4 -1
  6. package/dist/client/types/app/bsky/feed/getFeedGenerator.d.ts +21 -0
  7. package/dist/client/types/app/bsky/feed/getFeedSkeleton.d.ts +4 -1
  8. package/dist/client/types/app/bsky/feed/getSavedFeeds.d.ts +21 -0
  9. package/dist/client/types/app/bsky/feed/saveFeed.d.ts +17 -0
  10. package/dist/client/types/app/bsky/feed/unsaveFeed.d.ts +17 -0
  11. package/dist/client/types/com/atproto/admin/defs.d.ts +14 -2
  12. package/dist/client/types/com/atproto/admin/getModerationReports.d.ts +1 -0
  13. package/dist/client/types/com/atproto/admin/getRecord.d.ts +4 -1
  14. package/dist/client/types/com/atproto/admin/getRepo.d.ts +4 -1
  15. package/dist/client/types/com/atproto/server/createAccount.d.ts +7 -0
  16. package/dist/index.js +8910 -9
  17. package/dist/index.js.map +4 -4
  18. package/jest.bench.config.js +8 -0
  19. package/package.json +4 -2
  20. package/src/client/lexicons.ts +56 -0
  21. package/src/client/types/com/atproto/admin/defs.ts +46 -2
  22. package/src/client/types/com/atproto/admin/getModerationReports.ts +6 -0
  23. package/src/client/types/com/atproto/admin/getRecord.ts +7 -0
  24. package/src/client/types/com/atproto/admin/getRepo.ts +7 -0
  25. package/src/client/types/com/atproto/server/createAccount.ts +15 -0
  26. package/tests/agent.test.ts +63 -0
  27. package/tests/bsky-agent.test.ts +63 -0
  28. package/tsconfig.build.tsbuildinfo +1 -1
@@ -0,0 +1,8 @@
1
+ const base = require('./jest.config')
2
+
3
+ module.exports = {
4
+ ...base,
5
+ roots: ['<rootDir>/bench'],
6
+ testRegex: '(.*.bench.ts)',
7
+ testTimeout: 3000000,
8
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atproto/api",
3
- "version": "0.3.3",
3
+ "version": "0.3.5",
4
4
  "main": "dist/index.js",
5
5
  "scripts": {
6
6
  "codegen": "lex gen-api ./src/client ../../lexicons/com/atproto/*/* ../../lexicons/app/bsky/*/*",
@@ -10,7 +10,9 @@
10
10
  "update-main-to-src": "node ./update-pkg.js --update-main-to-src",
11
11
  "prepublish": "npm run update-main-to-dist",
12
12
  "postpublish": "npm run update-main-to-src",
13
- "test": "jest"
13
+ "test": "jest",
14
+ "bench": "jest --config jest.bench.config.js",
15
+ "bench:profile": "node --inspect-brk ../../node_modules/.bin/jest --config jest.bench.config.js"
14
16
  },
15
17
  "license": "MIT",
16
18
  "repository": {
@@ -100,7 +100,9 @@ export const schemaDict = {
100
100
  type: 'union',
101
101
  refs: [
102
102
  'lex:com.atproto.admin.defs#repoView',
103
+ 'lex:com.atproto.admin.defs#repoViewNotFound',
103
104
  'lex:com.atproto.admin.defs#recordView',
105
+ 'lex:com.atproto.admin.defs#recordViewNotFound',
104
106
  ],
105
107
  },
106
108
  subjectBlobs: {
@@ -274,7 +276,9 @@ export const schemaDict = {
274
276
  type: 'union',
275
277
  refs: [
276
278
  'lex:com.atproto.admin.defs#repoView',
279
+ 'lex:com.atproto.admin.defs#repoViewNotFound',
277
280
  'lex:com.atproto.admin.defs#recordView',
281
+ 'lex:com.atproto.admin.defs#recordViewNotFound',
278
282
  ],
279
283
  },
280
284
  reportedBy: {
@@ -396,6 +400,16 @@ export const schemaDict = {
396
400
  },
397
401
  },
398
402
  },
403
+ repoViewNotFound: {
404
+ type: 'object',
405
+ required: ['did'],
406
+ properties: {
407
+ did: {
408
+ type: 'string',
409
+ format: 'did',
410
+ },
411
+ },
412
+ },
399
413
  repoRef: {
400
414
  type: 'object',
401
415
  required: ['did'],
@@ -501,6 +515,16 @@ export const schemaDict = {
501
515
  },
502
516
  },
503
517
  },
518
+ recordViewNotFound: {
519
+ type: 'object',
520
+ required: ['uri'],
521
+ properties: {
522
+ uri: {
523
+ type: 'string',
524
+ format: 'at-uri',
525
+ },
526
+ },
527
+ },
504
528
  moderation: {
505
529
  type: 'object',
506
530
  required: [],
@@ -835,6 +859,15 @@ export const schemaDict = {
835
859
  resolved: {
836
860
  type: 'boolean',
837
861
  },
862
+ actionType: {
863
+ type: 'string',
864
+ knownValues: [
865
+ 'com.atproto.admin.defs#takedown',
866
+ 'com.atproto.admin.defs#flag',
867
+ 'com.atproto.admin.defs#acknowledge',
868
+ 'com.atproto.admin.defs#escalate',
869
+ ],
870
+ },
838
871
  limit: {
839
872
  type: 'integer',
840
873
  minimum: 1,
@@ -896,6 +929,11 @@ export const schemaDict = {
896
929
  ref: 'lex:com.atproto.admin.defs#recordViewDetail',
897
930
  },
898
931
  },
932
+ errors: [
933
+ {
934
+ name: 'RecordNotFound',
935
+ },
936
+ ],
899
937
  },
900
938
  },
901
939
  },
@@ -923,6 +961,11 @@ export const schemaDict = {
923
961
  ref: 'lex:com.atproto.admin.defs#repoViewDetail',
924
962
  },
925
963
  },
964
+ errors: [
965
+ {
966
+ name: 'RepoNotFound',
967
+ },
968
+ ],
926
969
  },
927
970
  },
928
971
  },
@@ -1576,6 +1619,7 @@ export const schemaDict = {
1576
1619
  },
1577
1620
  rkey: {
1578
1621
  type: 'string',
1622
+ maxLength: 15,
1579
1623
  },
1580
1624
  value: {
1581
1625
  type: 'unknown',
@@ -1641,6 +1685,7 @@ export const schemaDict = {
1641
1685
  rkey: {
1642
1686
  type: 'string',
1643
1687
  description: 'The key of the record.',
1688
+ maxLength: 15,
1644
1689
  },
1645
1690
  validate: {
1646
1691
  type: 'boolean',
@@ -1962,6 +2007,7 @@ export const schemaDict = {
1962
2007
  rkey: {
1963
2008
  type: 'string',
1964
2009
  description: 'The key of the record.',
2010
+ maxLength: 15,
1965
2011
  },
1966
2012
  validate: {
1967
2013
  type: 'boolean',
@@ -2114,6 +2160,10 @@ export const schemaDict = {
2114
2160
  type: 'string',
2115
2161
  format: 'handle',
2116
2162
  },
2163
+ did: {
2164
+ type: 'string',
2165
+ format: 'did',
2166
+ },
2117
2167
  inviteCode: {
2118
2168
  type: 'string',
2119
2169
  },
@@ -2165,6 +2215,12 @@ export const schemaDict = {
2165
2215
  {
2166
2216
  name: 'UnsupportedDomain',
2167
2217
  },
2218
+ {
2219
+ name: 'UnresolvableDid',
2220
+ },
2221
+ {
2222
+ name: 'IncompatibleDidDoc',
2223
+ },
2168
2224
  ],
2169
2225
  },
2170
2226
  },
@@ -43,7 +43,12 @@ export function validateActionView(v: unknown): ValidationResult {
43
43
  export interface ActionViewDetail {
44
44
  id: number
45
45
  action: ActionType
46
- subject: RepoView | RecordView | { $type: string; [k: string]: unknown }
46
+ subject:
47
+ | RepoView
48
+ | RepoViewNotFound
49
+ | RecordView
50
+ | RecordViewNotFound
51
+ | { $type: string; [k: string]: unknown }
47
52
  subjectBlobs: BlobView[]
48
53
  createLabelVals?: string[]
49
54
  negateLabelVals?: string[]
@@ -150,7 +155,12 @@ export interface ReportViewDetail {
150
155
  id: number
151
156
  reasonType: ComAtprotoModerationDefs.ReasonType
152
157
  reason?: string
153
- subject: RepoView | RecordView | { $type: string; [k: string]: unknown }
158
+ subject:
159
+ | RepoView
160
+ | RepoViewNotFound
161
+ | RecordView
162
+ | RecordViewNotFound
163
+ | { $type: string; [k: string]: unknown }
154
164
  reportedBy: string
155
165
  createdAt: string
156
166
  resolvedByActions: ActionView[]
@@ -219,6 +229,23 @@ export function validateRepoViewDetail(v: unknown): ValidationResult {
219
229
  return lexicons.validate('com.atproto.admin.defs#repoViewDetail', v)
220
230
  }
221
231
 
232
+ export interface RepoViewNotFound {
233
+ did: string
234
+ [k: string]: unknown
235
+ }
236
+
237
+ export function isRepoViewNotFound(v: unknown): v is RepoViewNotFound {
238
+ return (
239
+ isObj(v) &&
240
+ hasProp(v, '$type') &&
241
+ v.$type === 'com.atproto.admin.defs#repoViewNotFound'
242
+ )
243
+ }
244
+
245
+ export function validateRepoViewNotFound(v: unknown): ValidationResult {
246
+ return lexicons.validate('com.atproto.admin.defs#repoViewNotFound', v)
247
+ }
248
+
222
249
  export interface RepoRef {
223
250
  did: string
224
251
  [k: string]: unknown
@@ -283,6 +310,23 @@ export function validateRecordViewDetail(v: unknown): ValidationResult {
283
310
  return lexicons.validate('com.atproto.admin.defs#recordViewDetail', v)
284
311
  }
285
312
 
313
+ export interface RecordViewNotFound {
314
+ uri: string
315
+ [k: string]: unknown
316
+ }
317
+
318
+ export function isRecordViewNotFound(v: unknown): v is RecordViewNotFound {
319
+ return (
320
+ isObj(v) &&
321
+ hasProp(v, '$type') &&
322
+ v.$type === 'com.atproto.admin.defs#recordViewNotFound'
323
+ )
324
+ }
325
+
326
+ export function validateRecordViewNotFound(v: unknown): ValidationResult {
327
+ return lexicons.validate('com.atproto.admin.defs#recordViewNotFound', v)
328
+ }
329
+
286
330
  export interface Moderation {
287
331
  currentAction?: ActionViewCurrent
288
332
  [k: string]: unknown
@@ -11,6 +11,12 @@ import * as ComAtprotoAdminDefs from './defs'
11
11
  export interface QueryParams {
12
12
  subject?: string
13
13
  resolved?: boolean
14
+ actionType?:
15
+ | 'com.atproto.admin.defs#takedown'
16
+ | 'com.atproto.admin.defs#flag'
17
+ | 'com.atproto.admin.defs#acknowledge'
18
+ | 'com.atproto.admin.defs#escalate'
19
+ | (string & {})
14
20
  limit?: number
15
21
  cursor?: string
16
22
  }
@@ -26,8 +26,15 @@ export interface Response {
26
26
  data: OutputSchema
27
27
  }
28
28
 
29
+ export class RecordNotFoundError extends XRPCError {
30
+ constructor(src: XRPCError) {
31
+ super(src.status, src.error, src.message)
32
+ }
33
+ }
34
+
29
35
  export function toKnownErr(e: any) {
30
36
  if (e instanceof XRPCError) {
37
+ if (e.error === 'RecordNotFound') return new RecordNotFoundError(e)
31
38
  }
32
39
  return e
33
40
  }
@@ -25,8 +25,15 @@ export interface Response {
25
25
  data: OutputSchema
26
26
  }
27
27
 
28
+ export class RepoNotFoundError extends XRPCError {
29
+ constructor(src: XRPCError) {
30
+ super(src.status, src.error, src.message)
31
+ }
32
+ }
33
+
28
34
  export function toKnownErr(e: any) {
29
35
  if (e instanceof XRPCError) {
36
+ if (e.error === 'RepoNotFound') return new RepoNotFoundError(e)
30
37
  }
31
38
  return e
32
39
  }
@@ -12,6 +12,7 @@ export interface QueryParams {}
12
12
  export interface InputSchema {
13
13
  email: string
14
14
  handle: string
15
+ did?: string
15
16
  inviteCode?: string
16
17
  password: string
17
18
  recoveryKey?: string
@@ -68,6 +69,18 @@ export class UnsupportedDomainError extends XRPCError {
68
69
  }
69
70
  }
70
71
 
72
+ export class UnresolvableDidError extends XRPCError {
73
+ constructor(src: XRPCError) {
74
+ super(src.status, src.error, src.message)
75
+ }
76
+ }
77
+
78
+ export class IncompatibleDidDocError extends XRPCError {
79
+ constructor(src: XRPCError) {
80
+ super(src.status, src.error, src.message)
81
+ }
82
+ }
83
+
71
84
  export function toKnownErr(e: any) {
72
85
  if (e instanceof XRPCError) {
73
86
  if (e.error === 'InvalidHandle') return new InvalidHandleError(e)
@@ -75,6 +88,8 @@ export function toKnownErr(e: any) {
75
88
  if (e.error === 'InvalidInviteCode') return new InvalidInviteCodeError(e)
76
89
  if (e.error === 'HandleNotAvailable') return new HandleNotAvailableError(e)
77
90
  if (e.error === 'UnsupportedDomain') return new UnsupportedDomainError(e)
91
+ if (e.error === 'UnresolvableDid') return new UnresolvableDidError(e)
92
+ if (e.error === 'IncompatibleDidDoc') return new IncompatibleDidDocError(e)
78
93
  }
79
94
  return e
80
95
  }
@@ -398,4 +398,67 @@ describe('agent', () => {
398
398
  expect(sessions.length).toEqual(1)
399
399
  expect(sessions[0]?.accessJwt).toEqual(origAccessJwt)
400
400
  })
401
+
402
+ describe('setPersistSessionHandler', () => {
403
+ it('sets persist session handler', async () => {
404
+ let originalHandlerCallCount = 0
405
+ let newHandlerCallCount = 0
406
+
407
+ const persistSession = () => {
408
+ originalHandlerCallCount++
409
+ }
410
+ const newPersistSession = () => {
411
+ newHandlerCallCount++
412
+ }
413
+
414
+ const agent = new AtpAgent({ service: server.url, persistSession })
415
+
416
+ await agent.createAccount({
417
+ handle: 'user7.test',
418
+ email: 'user7@test.com',
419
+ password: 'password',
420
+ })
421
+
422
+ expect(originalHandlerCallCount).toEqual(1)
423
+
424
+ agent.setPersistSessionHandler(newPersistSession)
425
+
426
+ await agent.createAccount({
427
+ handle: 'user8.test',
428
+ email: 'user8@test.com',
429
+ password: 'password',
430
+ })
431
+
432
+ expect(originalHandlerCallCount).toEqual(1)
433
+ expect(newHandlerCallCount).toEqual(1)
434
+ })
435
+ })
436
+
437
+ describe('createAccount', () => {
438
+ it('persists an empty session on failure', async () => {
439
+ const events: string[] = []
440
+ const sessions: (AtpSessionData | undefined)[] = []
441
+ const persistSession = (evt: AtpSessionEvent, sess?: AtpSessionData) => {
442
+ events.push(evt)
443
+ sessions.push(sess)
444
+ }
445
+
446
+ const agent = new AtpAgent({ service: server.url, persistSession })
447
+
448
+ await expect(
449
+ agent.createAccount({
450
+ handle: '',
451
+ email: '',
452
+ password: 'password',
453
+ }),
454
+ ).rejects.toThrow()
455
+
456
+ expect(agent.hasSession).toEqual(false)
457
+ expect(agent.session).toEqual(undefined)
458
+ expect(events.length).toEqual(1)
459
+ expect(events[0]).toEqual('create-failed')
460
+ expect(sessions.length).toEqual(1)
461
+ expect(sessions[0]).toEqual(undefined)
462
+ })
463
+ })
401
464
  })
@@ -137,4 +137,67 @@ describe('agent', () => {
137
137
  })
138
138
  await expect(p).rejects.toThrow('Record/displayName must be a string')
139
139
  })
140
+
141
+ describe('app', () => {
142
+ it('should retrieve the api app', () => {
143
+ const agent = new BskyAgent({ service: server.url })
144
+ expect(agent.app).toBe(agent.api.app)
145
+ })
146
+ })
147
+
148
+ describe('post', () => {
149
+ it('should throw if no session', async () => {
150
+ const agent = new BskyAgent({ service: server.url })
151
+ await expect(agent.post({ text: 'foo' })).rejects.toThrow('Not logged in')
152
+ })
153
+ })
154
+
155
+ describe('deletePost', () => {
156
+ it('should throw if no session', async () => {
157
+ const agent = new BskyAgent({ service: server.url })
158
+ await expect(agent.deletePost('foo')).rejects.toThrow('Not logged in')
159
+ })
160
+ })
161
+
162
+ describe('like', () => {
163
+ it('should throw if no session', async () => {
164
+ const agent = new BskyAgent({ service: server.url })
165
+ await expect(agent.like('foo', 'bar')).rejects.toThrow('Not logged in')
166
+ })
167
+ })
168
+
169
+ describe('deleteLike', () => {
170
+ it('should throw if no session', async () => {
171
+ const agent = new BskyAgent({ service: server.url })
172
+ await expect(agent.deleteLike('foo')).rejects.toThrow('Not logged in')
173
+ })
174
+ })
175
+
176
+ describe('repost', () => {
177
+ it('should throw if no session', async () => {
178
+ const agent = new BskyAgent({ service: server.url })
179
+ await expect(agent.repost('foo', 'bar')).rejects.toThrow('Not logged in')
180
+ })
181
+ })
182
+
183
+ describe('deleteRepost', () => {
184
+ it('should throw if no session', async () => {
185
+ const agent = new BskyAgent({ service: server.url })
186
+ await expect(agent.deleteRepost('foo')).rejects.toThrow('Not logged in')
187
+ })
188
+ })
189
+
190
+ describe('follow', () => {
191
+ it('should throw if no session', async () => {
192
+ const agent = new BskyAgent({ service: server.url })
193
+ await expect(agent.follow('foo')).rejects.toThrow('Not logged in')
194
+ })
195
+ })
196
+
197
+ describe('deleteFollow', () => {
198
+ it('should throw if no session', async () => {
199
+ const agent = new BskyAgent({ service: server.url })
200
+ await expect(agent.deleteFollow('foo')).rejects.toThrow('Not logged in')
201
+ })
202
+ })
140
203
  })