@atproto/api 0.7.4 → 0.8.0

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/dist/types.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { LabelPreference } from './moderation/types';
2
- export declare type AtpSessionEvent = 'create' | 'create-failed' | 'update' | 'expired';
2
+ export declare type AtpSessionEvent = 'create' | 'create-failed' | 'update' | 'expired' | 'network-error';
3
3
  export interface AtpSessionData {
4
4
  refreshJwt: string;
5
5
  accessJwt: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atproto/api",
3
- "version": "0.7.4",
3
+ "version": "0.8.0",
4
4
  "license": "MIT",
5
5
  "description": "Client library for atproto and Bluesky",
6
6
  "keywords": [
@@ -28,7 +28,7 @@
28
28
  "devDependencies": {
29
29
  "common-tags": "^1.8.2",
30
30
  "@atproto/lex-cli": "^0.2.5",
31
- "@atproto/dev-env": "^0.2.21"
31
+ "@atproto/dev-env": "^0.2.22"
32
32
  },
33
33
  "scripts": {
34
34
  "codegen": "pnpm docgen && node ./scripts/generate-code.mjs && lex gen-api ./src/client ../../lexicons/com/atproto/*/* ../../lexicons/app/bsky/*/*",
package/src/agent.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { ErrorResponseBody, errorResponseBody } from '@atproto/xrpc'
2
- import { defaultFetchHandler } from '@atproto/xrpc'
2
+ import { defaultFetchHandler, XRPCError, ResponseType } from '@atproto/xrpc'
3
3
  import { isValidDidDoc, getPdsEndpoint } from '@atproto/common-web'
4
4
  import {
5
5
  AtpBaseClient,
@@ -159,23 +159,41 @@ export class AtpAgent {
159
159
  try {
160
160
  this.session = session
161
161
  const res = await this.api.com.atproto.server.getSession()
162
- if (!res.success || res.data.did !== this.session.did) {
163
- throw new Error('Invalid session')
162
+ if (res.data.did !== this.session.did) {
163
+ throw new XRPCError(
164
+ ResponseType.InvalidRequest,
165
+ 'Invalid session',
166
+ 'InvalidDID',
167
+ )
164
168
  }
165
169
  this.session.email = res.data.email
166
170
  this.session.handle = res.data.handle
167
171
  this.session.emailConfirmed = res.data.emailConfirmed
168
172
  this._updateApiEndpoint(res.data.didDoc)
173
+ this._persistSession?.('update', this.session)
169
174
  return res
170
175
  } catch (e) {
171
176
  this.session = undefined
172
- throw e
173
- } finally {
174
- if (this.session) {
175
- this._persistSession?.('create', this.session)
177
+
178
+ if (e instanceof XRPCError) {
179
+ /*
180
+ * `ExpiredToken` and `InvalidToken` are handled in
181
+ * `this_refreshSession`, and emit an `expired` event there.
182
+ *
183
+ * Everything else is handled here.
184
+ */
185
+ if (
186
+ [1, 408, 425, 429, 500, 502, 503, 504, 522, 524].includes(e.status)
187
+ ) {
188
+ this._persistSession?.('network-error', undefined)
189
+ } else {
190
+ this._persistSession?.('expired', undefined)
191
+ }
176
192
  } else {
177
- this._persistSession?.('create-failed', undefined)
193
+ this._persistSession?.('network-error', undefined)
178
194
  }
195
+
196
+ throw e
179
197
  }
180
198
  }
181
199
 
@@ -297,6 +297,7 @@ export const COM_ATPROTO_MODERATION = {
297
297
  DefsReasonSexual: 'com.atproto.moderation.defs#reasonSexual',
298
298
  DefsReasonRude: 'com.atproto.moderation.defs#reasonRude',
299
299
  DefsReasonOther: 'com.atproto.moderation.defs#reasonOther',
300
+ DefsReasonAppeal: 'com.atproto.moderation.defs#reasonAppeal',
300
301
  }
301
302
  export const APP_BSKY_GRAPH = {
302
303
  DefsModlist: 'app.bsky.graph.defs#modlist',
@@ -102,6 +102,7 @@ export const schemaDict = {
102
102
  'lex:com.atproto.admin.defs#modEventAcknowledge',
103
103
  'lex:com.atproto.admin.defs#modEventEscalate',
104
104
  'lex:com.atproto.admin.defs#modEventMute',
105
+ 'lex:com.atproto.admin.defs#modEventResolveAppeal',
105
106
  ],
106
107
  },
107
108
  subject: {
@@ -237,9 +238,20 @@ export const schemaDict = {
237
238
  type: 'string',
238
239
  format: 'datetime',
239
240
  },
241
+ lastAppealedAt: {
242
+ type: 'string',
243
+ format: 'datetime',
244
+ description:
245
+ 'Timestamp referencing when the author of the subject appealed a moderation action',
246
+ },
240
247
  takendown: {
241
248
  type: 'boolean',
242
249
  },
250
+ appealed: {
251
+ type: 'boolean',
252
+ description:
253
+ 'True indicates that the a previously taken moderator action was appealed against, by the author of the content. False indicates last appeal was resolved by moderators.',
254
+ },
243
255
  suspendUntil: {
244
256
  type: 'string',
245
257
  format: 'datetime',
@@ -717,6 +729,16 @@ export const schemaDict = {
717
729
  },
718
730
  },
719
731
  },
732
+ modEventResolveAppeal: {
733
+ type: 'object',
734
+ description: 'Resolve appeal on a subject',
735
+ properties: {
736
+ comment: {
737
+ type: 'string',
738
+ description: 'Describe resolution.',
739
+ },
740
+ },
741
+ },
720
742
  modEventComment: {
721
743
  type: 'object',
722
744
  description: 'Add a comment to a subject',
@@ -816,6 +838,10 @@ export const schemaDict = {
816
838
  type: 'string',
817
839
  description: 'The subject line of the email sent to the user.',
818
840
  },
841
+ comment: {
842
+ type: 'string',
843
+ description: 'Additional comment about the outgoing comm.',
844
+ },
819
845
  },
820
846
  },
821
847
  },
@@ -1357,6 +1383,10 @@ export const schemaDict = {
1357
1383
  type: 'boolean',
1358
1384
  description: 'Get subjects that were taken down',
1359
1385
  },
1386
+ appealed: {
1387
+ type: 'boolean',
1388
+ description: 'Get subjects in unresolved appealed status',
1389
+ },
1360
1390
  limit: {
1361
1391
  type: 'integer',
1362
1392
  minimum: 1,
@@ -1467,6 +1497,11 @@ export const schemaDict = {
1467
1497
  type: 'string',
1468
1498
  format: 'did',
1469
1499
  },
1500
+ comment: {
1501
+ type: 'string',
1502
+ description:
1503
+ "Additional comment by the sender that won't be used in the email itself but helpful to provide more context for moderators/reviewers",
1504
+ },
1470
1505
  },
1471
1506
  },
1472
1507
  },
@@ -1937,6 +1972,7 @@ export const schemaDict = {
1937
1972
  'com.atproto.moderation.defs#reasonSexual',
1938
1973
  'com.atproto.moderation.defs#reasonRude',
1939
1974
  'com.atproto.moderation.defs#reasonOther',
1975
+ 'com.atproto.moderation.defs#reasonAppeal',
1940
1976
  ],
1941
1977
  },
1942
1978
  reasonSpam: {
@@ -1964,6 +2000,10 @@ export const schemaDict = {
1964
2000
  type: 'token',
1965
2001
  description: 'Other: reports not falling under another report category',
1966
2002
  },
2003
+ reasonAppeal: {
2004
+ type: 'token',
2005
+ description: 'Appeal: appeal a previously taken moderation action',
2006
+ },
1967
2007
  },
1968
2008
  },
1969
2009
  ComAtprotoRepoApplyWrites: {
@@ -76,6 +76,7 @@ export interface ModEventViewDetail {
76
76
  | ModEventAcknowledge
77
77
  | ModEventEscalate
78
78
  | ModEventMute
79
+ | ModEventResolveAppeal
79
80
  | { $type: string; [k: string]: unknown }
80
81
  subject:
81
82
  | RepoView
@@ -147,7 +148,11 @@ export interface SubjectStatusView {
147
148
  lastReviewedBy?: string
148
149
  lastReviewedAt?: string
149
150
  lastReportedAt?: string
151
+ /** Timestamp referencing when the author of the subject appealed a moderation action */
152
+ lastAppealedAt?: string
150
153
  takendown?: boolean
154
+ /** True indicates that the a previously taken moderator action was appealed against, by the author of the content. False indicates last appeal was resolved by moderators. */
155
+ appealed?: boolean
151
156
  suspendUntil?: string
152
157
  [k: string]: unknown
153
158
  }
@@ -538,6 +543,27 @@ export function validateModEventReverseTakedown(v: unknown): ValidationResult {
538
543
  return lexicons.validate('com.atproto.admin.defs#modEventReverseTakedown', v)
539
544
  }
540
545
 
546
+ /** Resolve appeal on a subject */
547
+ export interface ModEventResolveAppeal {
548
+ /** Describe resolution. */
549
+ comment?: string
550
+ [k: string]: unknown
551
+ }
552
+
553
+ export function isModEventResolveAppeal(
554
+ v: unknown,
555
+ ): v is ModEventResolveAppeal {
556
+ return (
557
+ isObj(v) &&
558
+ hasProp(v, '$type') &&
559
+ v.$type === 'com.atproto.admin.defs#modEventResolveAppeal'
560
+ )
561
+ }
562
+
563
+ export function validateModEventResolveAppeal(v: unknown): ValidationResult {
564
+ return lexicons.validate('com.atproto.admin.defs#modEventResolveAppeal', v)
565
+ }
566
+
541
567
  /** Add a comment to a subject */
542
568
  export interface ModEventComment {
543
569
  comment: string
@@ -674,6 +700,8 @@ export function validateModEventUnmute(v: unknown): ValidationResult {
674
700
  export interface ModEventEmail {
675
701
  /** The subject line of the email sent to the user. */
676
702
  subjectLine: string
703
+ /** Additional comment about the outgoing comm. */
704
+ comment?: string
677
705
  [k: string]: unknown
678
706
  }
679
707
 
@@ -31,6 +31,8 @@ export interface QueryParams {
31
31
  sortDirection?: 'asc' | 'desc'
32
32
  /** Get subjects that were taken down */
33
33
  takendown?: boolean
34
+ /** Get subjects in unresolved appealed status */
35
+ appealed?: boolean
34
36
  limit?: number
35
37
  cursor?: string
36
38
  }
@@ -14,6 +14,8 @@ export interface InputSchema {
14
14
  content: string
15
15
  subject?: string
16
16
  senderDid: string
17
+ /** Additional comment by the sender that won't be used in the email itself but helpful to provide more context for moderators/reviewers */
18
+ comment?: string
17
19
  [k: string]: unknown
18
20
  }
19
21
 
@@ -13,6 +13,7 @@ export type ReasonType =
13
13
  | 'com.atproto.moderation.defs#reasonSexual'
14
14
  | 'com.atproto.moderation.defs#reasonRude'
15
15
  | 'com.atproto.moderation.defs#reasonOther'
16
+ | 'com.atproto.moderation.defs#reasonAppeal'
16
17
  | (string & {})
17
18
 
18
19
  /** Spam: frequent unwanted promotion, replies, mentions */
@@ -27,3 +28,5 @@ export const REASONSEXUAL = 'com.atproto.moderation.defs#reasonSexual'
27
28
  export const REASONRUDE = 'com.atproto.moderation.defs#reasonRude'
28
29
  /** Other: reports not falling under another report category */
29
30
  export const REASONOTHER = 'com.atproto.moderation.defs#reasonOther'
31
+ /** Appeal: appeal a previously taken moderation action */
32
+ export const REASONAPPEAL = 'com.atproto.moderation.defs#reasonAppeal'
package/src/types.ts CHANGED
@@ -3,7 +3,12 @@ import { LabelPreference } from './moderation/types'
3
3
  /**
4
4
  * Used by the PersistSessionHandler to indicate what change occurred
5
5
  */
6
- export type AtpSessionEvent = 'create' | 'create-failed' | 'update' | 'expired'
6
+ export type AtpSessionEvent =
7
+ | 'create'
8
+ | 'create-failed'
9
+ | 'update'
10
+ | 'expired'
11
+ | 'network-error'
7
12
 
8
13
  /**
9
14
  * Used by AtpAgent to store active sessions
@@ -159,7 +159,7 @@ describe('agent', () => {
159
159
 
160
160
  expect(events.length).toEqual(2)
161
161
  expect(events[0]).toEqual('create')
162
- expect(events[1]).toEqual('create')
162
+ expect(events[1]).toEqual('update')
163
163
  expect(sessions.length).toEqual(2)
164
164
  expect(sessions[0]?.accessJwt).toEqual(agent1.session?.accessJwt)
165
165
  expect(sessions[1]?.accessJwt).toEqual(agent2.session?.accessJwt)
@@ -343,7 +343,7 @@ describe('agent', () => {
343
343
 
344
344
  expect(events.length).toEqual(2)
345
345
  expect(events[0]).toEqual('create-failed')
346
- expect(events[1]).toEqual('create-failed')
346
+ expect(events[1]).toEqual('network-error')
347
347
  expect(sessions.length).toEqual(2)
348
348
  expect(typeof sessions[0]).toEqual('undefined')
349
349
  expect(typeof sessions[1]).toEqual('undefined')