@atproto/api 0.20.22 → 0.20.25

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 (64) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/dist/client/lexicons.d.ts +28 -12
  3. package/dist/client/lexicons.d.ts.map +1 -1
  4. package/dist/client/lexicons.js +14 -6
  5. package/dist/client/lexicons.js.map +1 -1
  6. package/dist/client/types/app/bsky/ageassurance/defs.d.ts +2 -0
  7. package/dist/client/types/app/bsky/ageassurance/defs.d.ts.map +1 -1
  8. package/dist/client/types/app/bsky/ageassurance/defs.js.map +1 -1
  9. package/package.json +22 -16
  10. package/definitions/labels.json +0 -170
  11. package/docs/moderation.md +0 -260
  12. package/jest.config.cjs +0 -23
  13. package/jest.d.ts +0 -20
  14. package/jest.setup.ts +0 -97
  15. package/scripts/code/labels.mjs +0 -77
  16. package/scripts/generate-code.mjs +0 -4
  17. package/src/age-assurance.test.ts +0 -218
  18. package/src/age-assurance.ts +0 -137
  19. package/src/agent.ts +0 -1645
  20. package/src/atp-agent.ts +0 -570
  21. package/src/bsky-agent.ts +0 -14
  22. package/src/const.ts +0 -1
  23. package/src/index.ts +0 -44
  24. package/src/mocker.ts +0 -220
  25. package/src/moderation/decision.ts +0 -389
  26. package/src/moderation/index.ts +0 -69
  27. package/src/moderation/mutewords.ts +0 -170
  28. package/src/moderation/subjects/account.ts +0 -44
  29. package/src/moderation/subjects/feed-generator.ts +0 -24
  30. package/src/moderation/subjects/notification.ts +0 -25
  31. package/src/moderation/subjects/post.ts +0 -433
  32. package/src/moderation/subjects/profile.ts +0 -26
  33. package/src/moderation/subjects/status.ts +0 -27
  34. package/src/moderation/subjects/user-list.ts +0 -48
  35. package/src/moderation/types.ts +0 -191
  36. package/src/moderation/ui.ts +0 -21
  37. package/src/moderation/util.ts +0 -111
  38. package/src/predicate.ts +0 -52
  39. package/src/rich-text/detection.ts +0 -146
  40. package/src/rich-text/rich-text.ts +0 -418
  41. package/src/rich-text/sanitization.ts +0 -42
  42. package/src/rich-text/unicode.ts +0 -47
  43. package/src/rich-text/util.ts +0 -15
  44. package/src/session-manager.ts +0 -5
  45. package/src/types.ts +0 -165
  46. package/src/util.ts +0 -96
  47. package/tests/atp-agent.test.ts +0 -3863
  48. package/tests/dispatcher.test.ts +0 -527
  49. package/tests/errors.test.ts +0 -29
  50. package/tests/moderation-behaviors.test.ts +0 -951
  51. package/tests/moderation-custom-labels.test.ts +0 -334
  52. package/tests/moderation-mutewords.test.ts +0 -1299
  53. package/tests/moderation-prefs.test.ts +0 -402
  54. package/tests/moderation-quoteposts.test.ts +0 -277
  55. package/tests/moderation.test.ts +0 -739
  56. package/tests/rich-text-detection.test.ts +0 -456
  57. package/tests/rich-text-sanitization.test.ts +0 -216
  58. package/tests/rich-text.test.ts +0 -705
  59. package/tests/util/echo-server.ts +0 -37
  60. package/tests/util/moderation-behavior.ts +0 -268
  61. package/tsconfig.build.json +0 -9
  62. package/tsconfig.build.tsbuildinfo +0 -1
  63. package/tsconfig.json +0 -7
  64. package/tsconfig.tests.json +0 -10
@@ -1,418 +0,0 @@
1
- /*
2
- = Rich Text Manipulation
3
-
4
- When we sanitize rich text, we have to update the entity indices as the
5
- text is modified. This can be modeled as inserts() and deletes() of the
6
- rich text string. The possible scenarios are outlined below, along with
7
- their expected behaviors.
8
-
9
- NOTE: Slices are start inclusive, end exclusive
10
-
11
- == richTextInsert()
12
-
13
- Target string:
14
-
15
- 0 1 2 3 4 5 6 7 8 910 // string indices
16
- h e l l o w o r l d // string value
17
- ^-------^ // target slice {start: 2, end: 7}
18
-
19
- Scenarios:
20
-
21
- A: ^ // insert "test" at 0
22
- B: ^ // insert "test" at 4
23
- C: ^ // insert "test" at 8
24
-
25
- A = before -> move both by num added
26
- B = inner -> move end by num added
27
- C = after -> noop
28
-
29
- Results:
30
-
31
- A: 0 1 2 3 4 5 6 7 8 910 // string indices
32
- t e s t h e l l o w // string value
33
- ^-------^ // target slice {start: 6, end: 11}
34
-
35
- B: 0 1 2 3 4 5 6 7 8 910 // string indices
36
- h e l l t e s t o w // string value
37
- ^---------------^ // target slice {start: 2, end: 11}
38
-
39
- C: 0 1 2 3 4 5 6 7 8 910 // string indices
40
- h e l l o w o t e s // string value
41
- ^-------^ // target slice {start: 2, end: 7}
42
-
43
- == richTextDelete()
44
-
45
- Target string:
46
-
47
- 0 1 2 3 4 5 6 7 8 910 // string indices
48
- h e l l o w o r l d // string value
49
- ^-------^ // target slice {start: 2, end: 7}
50
-
51
- Scenarios:
52
-
53
- A: ^---------------^ // remove slice {start: 0, end: 9}
54
- B: ^-----^ // remove slice {start: 7, end: 11}
55
- C: ^-----------^ // remove slice {start: 4, end: 11}
56
- D: ^-^ // remove slice {start: 3, end: 5}
57
- E: ^-----^ // remove slice {start: 1, end: 5}
58
- F: ^-^ // remove slice {start: 0, end: 2}
59
-
60
- A = entirely outer -> delete slice
61
- B = entirely after -> noop
62
- C = partially after -> move end to remove-start
63
- D = entirely inner -> move end by num removed
64
- E = partially before -> move start to remove-start index, move end by num removed
65
- F = entirely before -> move both by num removed
66
-
67
- Results:
68
-
69
- A: 0 1 2 3 4 5 6 7 8 910 // string indices
70
- l d // string value
71
- // target slice (deleted)
72
-
73
- B: 0 1 2 3 4 5 6 7 8 910 // string indices
74
- h e l l o w // string value
75
- ^-------^ // target slice {start: 2, end: 7}
76
-
77
- C: 0 1 2 3 4 5 6 7 8 910 // string indices
78
- h e l l // string value
79
- ^-^ // target slice {start: 2, end: 4}
80
-
81
- D: 0 1 2 3 4 5 6 7 8 910 // string indices
82
- h e l w o r l d // string value
83
- ^---^ // target slice {start: 2, end: 5}
84
-
85
- E: 0 1 2 3 4 5 6 7 8 910 // string indices
86
- h w o r l d // string value
87
- ^-^ // target slice {start: 1, end: 3}
88
-
89
- F: 0 1 2 3 4 5 6 7 8 910 // string indices
90
- l l o w o r l d // string value
91
- ^-------^ // target slice {start: 0, end: 5}
92
- */
93
-
94
- import {
95
- AppBskyFeedPost,
96
- AppBskyRichtextFacet,
97
- AtpBaseClient,
98
- } from '../client/index.js'
99
- import { detectFacets } from './detection.js'
100
- import { sanitizeRichText } from './sanitization.js'
101
- import { UnicodeString } from './unicode.js'
102
-
103
- export type Facet = AppBskyRichtextFacet.Main
104
- export type FacetLink = AppBskyRichtextFacet.Link
105
- export type FacetMention = AppBskyRichtextFacet.Mention
106
- export type FacetTag = AppBskyRichtextFacet.Tag
107
- export type Entity = AppBskyFeedPost.Entity
108
-
109
- export interface RichTextProps {
110
- text: string
111
- facets?: Facet[]
112
- /**
113
- * @deprecated Use facets instead
114
- */
115
- entities?: Entity[]
116
- }
117
-
118
- export interface RichTextOpts {
119
- cleanNewlines?: boolean
120
- }
121
-
122
- export class RichTextSegment {
123
- constructor(
124
- public text: string,
125
- public facet?: Facet,
126
- ) {}
127
-
128
- get link(): FacetLink | undefined {
129
- return this.facet?.features.find(AppBskyRichtextFacet.isLink)
130
- }
131
-
132
- isLink() {
133
- return !!this.link
134
- }
135
-
136
- get mention(): FacetMention | undefined {
137
- return this.facet?.features.find(AppBskyRichtextFacet.isMention)
138
- }
139
-
140
- isMention() {
141
- return !!this.mention
142
- }
143
-
144
- get tag(): FacetTag | undefined {
145
- return this.facet?.features.find(AppBskyRichtextFacet.isTag)
146
- }
147
-
148
- isTag() {
149
- return !!this.tag
150
- }
151
- }
152
-
153
- export class RichText {
154
- unicodeText: UnicodeString
155
- facets?: Facet[]
156
-
157
- constructor(props: RichTextProps, opts?: RichTextOpts) {
158
- this.unicodeText = new UnicodeString(props.text)
159
- this.facets = props.facets
160
- if (!this.facets?.length && props.entities?.length) {
161
- this.facets = entitiesToFacets(this.unicodeText, props.entities)
162
- }
163
- if (this.facets) {
164
- this.facets = this.facets.filter(facetFilter).sort(facetSort)
165
- }
166
- if (opts?.cleanNewlines) {
167
- sanitizeRichText(this, { cleanNewlines: true }).copyInto(this)
168
- }
169
- }
170
-
171
- get text() {
172
- return this.unicodeText.toString()
173
- }
174
-
175
- get length() {
176
- return this.unicodeText.length
177
- }
178
-
179
- get graphemeLength() {
180
- return this.unicodeText.graphemeLength
181
- }
182
-
183
- clone() {
184
- return new RichText({
185
- text: this.unicodeText.utf16,
186
- facets: cloneDeep(this.facets),
187
- })
188
- }
189
-
190
- copyInto(target: RichText) {
191
- target.unicodeText = this.unicodeText
192
- target.facets = cloneDeep(this.facets)
193
- }
194
-
195
- *segments(): Generator<RichTextSegment, void, void> {
196
- const facets = this.facets || []
197
- if (!facets.length) {
198
- yield new RichTextSegment(this.unicodeText.utf16)
199
- return
200
- }
201
-
202
- let textCursor = 0
203
- let facetCursor = 0
204
- do {
205
- const currFacet = facets[facetCursor]
206
- if (textCursor < currFacet.index.byteStart) {
207
- yield new RichTextSegment(
208
- this.unicodeText.slice(textCursor, currFacet.index.byteStart),
209
- )
210
- } else if (textCursor > currFacet.index.byteStart) {
211
- facetCursor++
212
- continue
213
- }
214
- if (currFacet.index.byteStart < currFacet.index.byteEnd) {
215
- const subtext = this.unicodeText.slice(
216
- currFacet.index.byteStart,
217
- currFacet.index.byteEnd,
218
- )
219
- if (!subtext.trim()) {
220
- // dont empty string entities
221
- yield new RichTextSegment(subtext)
222
- } else {
223
- yield new RichTextSegment(subtext, currFacet)
224
- }
225
- }
226
- textCursor = currFacet.index.byteEnd
227
- facetCursor++
228
- } while (facetCursor < facets.length)
229
- if (textCursor < this.unicodeText.length) {
230
- yield new RichTextSegment(
231
- this.unicodeText.slice(textCursor, this.unicodeText.length),
232
- )
233
- }
234
- }
235
-
236
- insert(insertIndex: number, insertText: string) {
237
- this.unicodeText = new UnicodeString(
238
- this.unicodeText.slice(0, insertIndex) +
239
- insertText +
240
- this.unicodeText.slice(insertIndex),
241
- )
242
-
243
- if (!this.facets?.length) {
244
- return this
245
- }
246
-
247
- const numCharsAdded = insertText.length
248
- for (const ent of this.facets) {
249
- // see comment at top of file for labels of each scenario
250
- // scenario A (before)
251
- if (insertIndex <= ent.index.byteStart) {
252
- // move both by num added
253
- ent.index.byteStart += numCharsAdded
254
- ent.index.byteEnd += numCharsAdded
255
- }
256
- // scenario B (inner)
257
- else if (
258
- insertIndex >= ent.index.byteStart &&
259
- insertIndex < ent.index.byteEnd
260
- ) {
261
- // move end by num added
262
- ent.index.byteEnd += numCharsAdded
263
- }
264
- // scenario C (after)
265
- // noop
266
- }
267
- return this
268
- }
269
-
270
- delete(removeStartIndex: number, removeEndIndex: number) {
271
- this.unicodeText = new UnicodeString(
272
- this.unicodeText.slice(0, removeStartIndex) +
273
- this.unicodeText.slice(removeEndIndex),
274
- )
275
-
276
- if (!this.facets?.length) {
277
- return this
278
- }
279
-
280
- const numCharsRemoved = removeEndIndex - removeStartIndex
281
- for (const ent of this.facets) {
282
- // see comment at top of file for labels of each scenario
283
- // scenario A (entirely outer)
284
- if (
285
- removeStartIndex <= ent.index.byteStart &&
286
- removeEndIndex >= ent.index.byteEnd
287
- ) {
288
- // delete slice (will get removed in final pass)
289
- ent.index.byteStart = 0
290
- ent.index.byteEnd = 0
291
- }
292
- // scenario B (entirely after)
293
- else if (removeStartIndex > ent.index.byteEnd) {
294
- // noop
295
- }
296
- // scenario C (partially after)
297
- else if (
298
- removeStartIndex > ent.index.byteStart &&
299
- removeStartIndex <= ent.index.byteEnd &&
300
- removeEndIndex > ent.index.byteEnd
301
- ) {
302
- // move end to remove start
303
- ent.index.byteEnd = removeStartIndex
304
- }
305
- // scenario D (entirely inner)
306
- else if (
307
- removeStartIndex >= ent.index.byteStart &&
308
- removeEndIndex <= ent.index.byteEnd
309
- ) {
310
- // move end by num removed
311
- ent.index.byteEnd -= numCharsRemoved
312
- }
313
- // scenario E (partially before)
314
- else if (
315
- removeStartIndex < ent.index.byteStart &&
316
- removeEndIndex >= ent.index.byteStart &&
317
- removeEndIndex <= ent.index.byteEnd
318
- ) {
319
- // move start to remove-start index, move end by num removed
320
- ent.index.byteStart = removeStartIndex
321
- ent.index.byteEnd -= numCharsRemoved
322
- }
323
- // scenario F (entirely before)
324
- else if (removeEndIndex < ent.index.byteStart) {
325
- // move both by num removed
326
- ent.index.byteStart -= numCharsRemoved
327
- ent.index.byteEnd -= numCharsRemoved
328
- }
329
- }
330
-
331
- // filter out any facets that were made irrelevant
332
- this.facets = this.facets.filter(
333
- (ent) => ent.index.byteStart < ent.index.byteEnd,
334
- )
335
- return this
336
- }
337
-
338
- /**
339
- * Detects facets such as links and mentions
340
- * Note: Overwrites the existing facets with auto-detected facets
341
- */
342
- async detectFacets(agent: AtpBaseClient) {
343
- this.facets = detectFacets(this.unicodeText)
344
- if (this.facets) {
345
- const promises: Promise<void>[] = []
346
- for (const facet of this.facets) {
347
- for (const feature of facet.features) {
348
- if (AppBskyRichtextFacet.isMention(feature)) {
349
- promises.push(
350
- agent.com.atproto.identity
351
- .resolveHandle({ handle: feature.did })
352
- .then((res) => res?.data.did)
353
- .catch((_) => undefined)
354
- .then((did) => {
355
- feature.did = did || ''
356
- }),
357
- )
358
- }
359
- }
360
- }
361
- await Promise.allSettled(promises)
362
- this.facets.sort(facetSort)
363
- }
364
- }
365
-
366
- /**
367
- * Detects facets such as links and mentions but does not resolve them
368
- * Will produce invalid facets! For instance, mentions will not have their DIDs set.
369
- * Note: Overwrites the existing facets with auto-detected facets
370
- */
371
- detectFacetsWithoutResolution() {
372
- this.facets = detectFacets(this.unicodeText)
373
- if (this.facets) {
374
- this.facets.sort(facetSort)
375
- }
376
- }
377
- }
378
-
379
- const facetSort = (a: Facet, b: Facet) => a.index.byteStart - b.index.byteStart
380
-
381
- const facetFilter = (facet: Facet) =>
382
- // discard negative-length facets. zero-length facets are valid
383
- facet.index.byteStart <= facet.index.byteEnd
384
-
385
- function entitiesToFacets(text: UnicodeString, entities: Entity[]): Facet[] {
386
- const facets: Facet[] = []
387
- for (const ent of entities) {
388
- if (ent.type === 'link') {
389
- facets.push({
390
- $type: 'app.bsky.richtext.facet',
391
- index: {
392
- byteStart: text.utf16IndexToUtf8Index(ent.index.start),
393
- byteEnd: text.utf16IndexToUtf8Index(ent.index.end),
394
- },
395
- features: [{ $type: 'app.bsky.richtext.facet#link', uri: ent.value }],
396
- })
397
- } else if (ent.type === 'mention') {
398
- facets.push({
399
- $type: 'app.bsky.richtext.facet',
400
- index: {
401
- byteStart: text.utf16IndexToUtf8Index(ent.index.start),
402
- byteEnd: text.utf16IndexToUtf8Index(ent.index.end),
403
- },
404
- features: [
405
- { $type: 'app.bsky.richtext.facet#mention', did: ent.value },
406
- ],
407
- })
408
- }
409
- }
410
- return facets
411
- }
412
-
413
- function cloneDeep<T>(v: T): T {
414
- if (typeof v === 'undefined') {
415
- return v
416
- }
417
- return JSON.parse(JSON.stringify(v))
418
- }
@@ -1,42 +0,0 @@
1
- import { RichText } from './rich-text.js'
2
- import { UnicodeString } from './unicode.js'
3
-
4
- // this regex is intentionally matching on the zero-with-separator codepoint
5
- // eslint-disable-next-line no-misleading-character-class
6
- const EXCESS_SPACE_RE = /[\r\n]([\u00AD\u2060\u200D\u200C\u200B\s]*[\r\n]){2,}/
7
- const REPLACEMENT_STR = '\n\n'
8
-
9
- export function sanitizeRichText(
10
- richText: RichText,
11
- opts: { cleanNewlines?: boolean },
12
- ) {
13
- if (opts.cleanNewlines) {
14
- richText = clean(richText, EXCESS_SPACE_RE, REPLACEMENT_STR)
15
- }
16
- return richText
17
- }
18
-
19
- function clean(
20
- richText: RichText,
21
- targetRegexp: RegExp,
22
- replacementString: string,
23
- ): RichText {
24
- richText = richText.clone()
25
-
26
- let match = richText.unicodeText.utf16.match(targetRegexp)
27
- while (match && typeof match.index !== 'undefined') {
28
- const oldText = richText.unicodeText
29
- const removeStartIndex = richText.unicodeText.utf16IndexToUtf8Index(
30
- match.index,
31
- )
32
- const removeEndIndex = removeStartIndex + new UnicodeString(match[0]).length
33
- richText.delete(removeStartIndex, removeEndIndex)
34
- if (richText.unicodeText.utf16 === oldText.utf16) {
35
- break // sanity check
36
- }
37
- richText.insert(removeStartIndex, replacementString)
38
- match = richText.unicodeText.utf16.match(targetRegexp)
39
- }
40
-
41
- return richText
42
- }
@@ -1,47 +0,0 @@
1
- /**
2
- * Javascript uses utf16-encoded strings while most environments and specs
3
- * have standardized around utf8 (including JSON).
4
- *
5
- * After some lengthy debated we decided that richtext facets need to use
6
- * utf8 indices. This means we need tools to convert indices between utf8
7
- * and utf16, and that's precisely what this library handles.
8
- */
9
-
10
- import { graphemeLen } from '@atproto/common-web'
11
-
12
- const encoder = new TextEncoder()
13
- const decoder = new TextDecoder()
14
-
15
- export class UnicodeString {
16
- utf16: string
17
- utf8: Uint8Array
18
- private _graphemeLen?: number | undefined
19
-
20
- constructor(utf16: string) {
21
- this.utf16 = utf16
22
- this.utf8 = encoder.encode(utf16)
23
- }
24
-
25
- get length() {
26
- return this.utf8.byteLength
27
- }
28
-
29
- get graphemeLength() {
30
- if (!this._graphemeLen) {
31
- this._graphemeLen = graphemeLen(this.utf16)
32
- }
33
- return this._graphemeLen
34
- }
35
-
36
- slice(start?: number, end?: number): string {
37
- return decoder.decode(this.utf8.slice(start, end))
38
- }
39
-
40
- utf16IndexToUtf8Index(i: number) {
41
- return encoder.encode(this.utf16.slice(0, i)).byteLength
42
- }
43
-
44
- toString() {
45
- return this.utf16
46
- }
47
- }
@@ -1,15 +0,0 @@
1
- export const MENTION_REGEX = /(^|\s|\()(@)([a-zA-Z0-9.-]+)(\b)/g
2
- export const URL_REGEX =
3
- /(^|\s|\()((https?:\/\/[\S]+)|((?<domain>[a-z][a-z0-9]*(\.[a-z0-9]+)+)[\S]*))/gim
4
- export const TRAILING_PUNCTUATION_REGEX = /\p{P}+$/gu
5
-
6
- /**
7
- * `\ufe0f` emoji modifier
8
- * `\u00AD\u2060\u200A\u200B\u200C\u200D\u20e2` zero-width spaces (likely incomplete)
9
- */
10
- export const TAG_REGEX =
11
- // eslint-disable-next-line no-misleading-character-class
12
- /(^|\s)[##]((?!\ufe0f)[^\s\u00AD\u2060\u200A\u200B\u200C\u200D\u20e2]*[^\d\s\p{P}\u00AD\u2060\u200A\u200B\u200C\u200D\u20e2]+[^\s\u00AD\u2060\u200A\u200B\u200C\u200D\u20e2]*)?/gu
13
-
14
- export const CASHTAG_REGEX =
15
- /(^|\s|\()\$([A-Za-z][A-Za-z0-9]{0,4})(?=\s|$|[.,;:!?)"'\u2019])/gu
@@ -1,5 +0,0 @@
1
- import { FetchHandlerObject } from '@atproto/xrpc'
2
-
3
- export interface SessionManager extends FetchHandlerObject {
4
- readonly did?: string
5
- }
package/src/types.ts DELETED
@@ -1,165 +0,0 @@
1
- import { AppBskyActorDefs } from './client/index.js'
2
- import { ModerationPrefs } from './moderation/types.js'
3
-
4
- export type UnknownServiceType = string & NonNullable<unknown>
5
- export type AtprotoServiceType = 'atproto_labeler' | UnknownServiceType
6
- export function isAtprotoServiceType<T extends string>(
7
- input: T,
8
- ): input is T & AtprotoServiceType {
9
- return !input.includes(' ') && !input.includes('#')
10
- }
11
-
12
- // @TODO use tools from @atproto/did
13
- export type Did = `did:${string}:${string}`
14
- export function isDid<T extends string>(input: T): input is T & Did {
15
- if (!input.startsWith('did:')) return false
16
- if (input.length < 8) return false
17
- if (input.length > 2048) return false
18
- const msidx = input.indexOf(':', 4)
19
- return msidx > 4 && msidx < input.length - 1
20
- }
21
-
22
- export function assertDid(input: string): asserts input is Did {
23
- if (!isDid(input)) throw new TypeError(`Invalid DID: ${input}`)
24
- }
25
-
26
- export function asDid<T extends string>(input: T) {
27
- assertDid(input)
28
- return input
29
- }
30
-
31
- export type AtprotoProxy = `${Did}#${AtprotoServiceType}`
32
- export function isAtprotoProxy(input: string): input is AtprotoProxy {
33
- const { length, [0]: did, [1]: service } = input.split('#')
34
- return length === 2 && isDid(did) && isAtprotoServiceType(service)
35
- }
36
-
37
- export function assertAtprotoProxy(
38
- input: string,
39
- ): asserts input is AtprotoProxy {
40
- if (!isAtprotoProxy(input)) {
41
- throw new TypeError(
42
- `Invalid DID reference: ${input} (must be of the form did:example:alice#service)`,
43
- )
44
- }
45
- }
46
-
47
- export function asAtprotoProxy<T extends string>(input: T) {
48
- assertAtprotoProxy(input)
49
- return input
50
- }
51
-
52
- /**
53
- * Used by the PersistSessionHandler to indicate what change occurred
54
- */
55
- export type AtpSessionEvent =
56
- | 'create'
57
- | 'create-failed'
58
- | 'update'
59
- | 'expired'
60
- | 'network-error'
61
-
62
- /**
63
- * Used by AtpAgent to store active sessions
64
- */
65
- export interface AtpSessionData {
66
- refreshJwt: string
67
- accessJwt: string
68
- handle: string
69
- did: string
70
- email?: string
71
- emailConfirmed?: boolean
72
- emailAuthFactor?: boolean
73
- active: boolean
74
- status?: string
75
- }
76
-
77
- /**
78
- * Handler signature passed to AtpAgent to store session data
79
- */
80
- export type AtpPersistSessionHandler = (
81
- evt: AtpSessionEvent,
82
- session: AtpSessionData | undefined,
83
- ) => void | Promise<void>
84
-
85
- /**
86
- * AtpAgent login() opts
87
- */
88
- export interface AtpAgentLoginOpts {
89
- identifier: string
90
- password: string
91
- authFactorToken?: string | undefined
92
- allowTakendown?: boolean
93
- }
94
-
95
- /**
96
- * AtpAgent global config opts
97
- */
98
- export interface AtpAgentGlobalOpts {
99
- appLabelers?: string[]
100
- }
101
-
102
- /**
103
- * Bluesky feed view preferences
104
- */
105
-
106
- export interface BskyFeedViewPreference {
107
- hideReplies: boolean
108
- hideRepliesByUnfollowed: boolean
109
- hideRepliesByLikeCount: number
110
- hideReposts: boolean
111
- hideQuotePosts: boolean
112
- [key: string]: any
113
- }
114
-
115
- /**
116
- * Bluesky thread view preferences
117
- */
118
- export interface BskyThreadViewPreference {
119
- sort: string
120
- [key: string]: any
121
- }
122
-
123
- /**
124
- * Bluesky interests preferences
125
- */
126
- export interface BskyInterestsPreference {
127
- tags: string[]
128
- [key: string]: any
129
- }
130
-
131
- /**
132
- * Bluesky preferences
133
- */
134
- export interface BskyPreferences {
135
- /**
136
- * @deprecated use `savedFeeds`
137
- */
138
- feeds: {
139
- saved?: string[]
140
- pinned?: string[]
141
- }
142
- savedFeeds: AppBskyActorDefs.SavedFeed[]
143
- feedViewPrefs: Record<string, BskyFeedViewPreference>
144
- threadViewPrefs: BskyThreadViewPreference
145
- moderationPrefs: ModerationPrefs
146
- birthDate: Date | undefined
147
- /**
148
- * Read-only preference containing value(s) inferred from the user's declared
149
- * birthdate. Absence of this preference object in the response indicates
150
- * that the user has not made a declaration.
151
- */
152
- declaredAge?: AppBskyActorDefs.DeclaredAgePref
153
- interests: BskyInterestsPreference
154
- bskyAppState: {
155
- queuedNudges: string[]
156
- activeProgressGuide: AppBskyActorDefs.BskyAppProgressGuide | undefined
157
- nuxs: AppBskyActorDefs.Nux[]
158
- }
159
- postInteractionSettings: AppBskyActorDefs.PostInteractionSettingsPref
160
- verificationPrefs: AppBskyActorDefs.VerificationPrefs
161
- liveEventPreferences: {
162
- hiddenFeedIds: string[]
163
- hideAllFeeds: boolean
164
- }
165
- }